home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 February / maximum-cd-2009-02.iso / DiscContents / SMC_1.6_win32.exe / src / level / level.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2008-09-24  |  73.0 KB  |  2,583 lines

  1. /***************************************************************************
  2.  * level.cpp  -  level handling 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 "../level/level.h"
  17. #include "../level/level_editor.h"
  18. #include "../core/game_core.h"
  19. #include "../core/main.h"
  20. #include "../core/camera.h"
  21. #include "../gui/hud.h"
  22. #include "../gui/menu.h"
  23. #include "../user/preferences.h"
  24. #include "../audio/audio.h"
  25. #include "../audio/random_sound.h"
  26. #include "../core/framerate.h"
  27. #include "../player/player.h"
  28. #include "../core/obj_manager.h"
  29. #include "../objects/goldpiece.h"
  30. #include "../objects/levelexit.h"
  31. #include "../objects/level_entry.h"
  32. #include "../video/font.h"
  33. #include "../input/keyboard.h"
  34. #include "../input/mouse.h"
  35. #include "../input/joystick.h"
  36. #include "../user/savegame.h"
  37. #include "../overworld/world_manager.h"
  38. #include "../overworld/overworld.h"
  39. #include "../enemies/turtle.h"
  40. #include "../enemies/bosses/turtle_boss.h"
  41. #include "../enemies/rokko.h"
  42. #include "../enemies/krush.h"
  43. #include "../enemies/furball.h"
  44. #include "../enemies/jpiranha.h"
  45. #include "../enemies/thromp.h"
  46. #include "../enemies/eato.h"
  47. #include "../enemies/gee.h"
  48. #include "../enemies/spika.h"
  49. #include "../enemies/static.h"
  50. #include "../objects/powerup.h"
  51. #include "../objects/enemystopper.h"
  52. #include "../objects/spinbox.h"
  53. #include "../objects/bonusbox.h"
  54. #include "../objects/text_box.h"
  55. #include "../objects/moving_platform.h"
  56. #include "../video/renderer.h"
  57. #include "../video/gl_surface.h"
  58. #include "../core/sprite_manager.h"
  59. #include "../video/animation.h"
  60. #include "../core/math/utilities.h"
  61. #include "../core/i18n.h"
  62.  
  63.  
  64. /* *** *** *** *** *** cLevel *** *** *** *** *** *** *** *** *** *** *** *** */
  65.  
  66. cLevel :: cLevel( void )
  67. : cFile_parser()
  68. {
  69.     engine_version = -1; // no version
  70.     last_saved = 0;
  71.  
  72.     musicfile.clear();
  73.     valid_music = 0;
  74.  
  75.     levelfile.clear();
  76.     next_levelfile.clear();
  77.  
  78.     author.clear();
  79.     version.clear();
  80.     delayed_unload = 0;
  81.  
  82.     background_manager = new cBackground_Manager();
  83.     pGlobal_effect = new cGlobal_effect();
  84.     pSprite_Manager = new cSprite_Manager();
  85.  
  86.     // add default gradient layer
  87.     cBackground *gradient_background = new cBackground();
  88.     gradient_background->Set_Type( BG_GR_VER );
  89.     gradient_background->posz = 0.0001f;
  90.     background_manager->Add( gradient_background );
  91. }
  92.  
  93. cLevel :: ~cLevel( void )
  94. {
  95.     Unload();
  96.  
  97.     // delete
  98.     delete background_manager;
  99.     delete pGlobal_effect;
  100.     delete pSprite_Manager;
  101. }
  102.  
  103. bool cLevel :: New( string filename )
  104. {
  105.     Unload();
  106.  
  107.     ifstream ifs;
  108.  
  109.     // if no name is given create name
  110.     if( filename.empty() )
  111.     {
  112.         unsigned int i = 1;
  113.  
  114.         // search for a not existing file
  115.         while( 1 )
  116.         {
  117.             // set name
  118.             filename = user_data_dir + USER_LEVEL_DIR + "/new_" + int_to_string( i ) + ".smclvl";
  119.             // try to open the file
  120.             ifs.open( filename.c_str(), ios::in );
  121.  
  122.             // found unused name
  123.             if( !ifs.is_open() )
  124.             {
  125.                 break;
  126.             }
  127.  
  128.             // stop on 99
  129.             if( i > 99 )
  130.             {
  131.                 return 0;
  132.             }
  133.             
  134.             ifs.close();
  135.             i++;
  136.         }
  137.     }
  138.     else
  139.     {
  140.         // set file type
  141.         if( filename.find( ".smclvl" ) == string::npos )
  142.         {
  143.             filename.insert( filename.length(), ".smclvl" );
  144.         }
  145.  
  146.         // set user directory
  147.         if( filename.find( user_data_dir + USER_LEVEL_DIR + "/" ) == string::npos )
  148.         {
  149.             filename.insert( 0, user_data_dir + USER_LEVEL_DIR + "/" );
  150.         }
  151.     }
  152.  
  153.     // open file
  154.     ifs.open( filename.c_str(), ios::in );
  155.  
  156.     // Level doesn't exist
  157.     if( !ifs )
  158.     {
  159.         // set filename
  160.         levelfile = filename;
  161.         data_file = Get_Filename( filename, 0, 1 );
  162.  
  163.         engine_version = level_engine_version;
  164.  
  165.         // set default music
  166.         musicfile = DATA_DIR "/" GAME_MUSIC_DIR "/" LEVEL_DEFAULT_MUSIC;
  167.         valid_music = File_Exists( musicfile );
  168.  
  169.         return 1;
  170.     }
  171.  
  172.     // Level already exists
  173.     ifs.close();
  174.     return 0;
  175. }
  176.  
  177. bool cLevel :: Load( string filename, bool delayed /* = 0 */ )
  178. {
  179.     next_levelfile.clear();
  180.  
  181.     if( !Get_Path( filename ) )
  182.     {
  183.         // show error without directory and file type
  184.         printf( "Couldn't load level : %s\n", Get_Filename( filename, 0, 0 ).c_str() );
  185.         return 0;
  186.     }
  187.  
  188.     if( delayed )
  189.     {
  190.         next_levelfile = filename;
  191.         return 1;
  192.     }
  193.  
  194.     Unload();
  195.  
  196.     levelfile = filename;
  197.  
  198.     // set default music
  199.     musicfile = DATA_DIR "/" GAME_MUSIC_DIR "/" LEVEL_DEFAULT_MUSIC;
  200.     valid_music = File_Exists( musicfile );
  201.  
  202.     // new level format
  203.     if( filename.rfind( ".smclvl" ) != string::npos )
  204.     {
  205.         try
  206.         {
  207.             CEGUI::System::getSingleton().getXMLParser()->parseXMLFile( *this, filename.c_str(), DATA_DIR "/" GAME_SCHEMA_DIR "/Level.xsd", "" );
  208.         }
  209.         // catch CEGUI Exceptions
  210.         catch( CEGUI::Exception &ex )
  211.         {
  212.             printf( "Loading Level %s CEGUI Exception %s\n", filename.c_str(), ex.getMessage().c_str() );
  213.             debugdisplay->Set_Text( _("Loading Level failed : ") + (string)ex.getMessage().c_str() );
  214.             return 0;
  215.         }
  216.  
  217.         // set parser filename for compatibility
  218.         data_file = filename;
  219.     }
  220.     // parse old level format
  221.     else
  222.     {
  223.         Parse( filename );
  224.  
  225.         // always use default direction
  226.         pPlayer->Set_Direction( DIR_RIGHT, 1 );
  227.     }
  228.  
  229.     // hack : save current camera position
  230.     float cam_x = pActive_Camera->x;
  231.     float cam_y = pActive_Camera->y;
  232.  
  233.     // hack : use level camera position for global effect initialization
  234.     pActive_Camera->Center();
  235.  
  236.     // init global effect
  237.     pGlobal_effect->Init_Anim();
  238.     
  239.     // hack : set back old position
  240.     pActive_Camera->Set_Pos( cam_x, cam_y );
  241.  
  242.     // engine version entry not set
  243.     if( engine_version < 0 )
  244.     {
  245.         engine_version = 0;
  246.     }
  247.  
  248.     return 1;
  249. }
  250.  
  251. void cLevel :: Unload( bool delayed /* = 0 */ )
  252. {
  253.     if( delayed )
  254.     {
  255.         delayed_unload = 1;
  256.         return;
  257.     }
  258.     else
  259.     {
  260.         delayed_unload = 0;
  261.     }
  262.  
  263.     // not loaded
  264.     if( !Is_Loaded() )
  265.     {
  266.         return;
  267.     }
  268.  
  269.     // delete backgrounds
  270.     background_manager->Delete_All();
  271.  
  272.     // add default gradient layer
  273.     cBackground *gradient_background = new cBackground();
  274.     gradient_background->Set_Type( BG_GR_VER );
  275.     gradient_background->posz = 0.0001f;
  276.     background_manager->Add( gradient_background );
  277.  
  278.     // reset music
  279.     musicfile.clear();
  280.  
  281.     valid_music = 0;
  282.  
  283.     author.clear();
  284.     version.clear();
  285.  
  286.     // reset camera limits
  287.     pLevel_Manager->camera->Reset_Limits();
  288.  
  289.     // clear global effect
  290.     pGlobal_effect->Clear();
  291.  
  292.     // reset time display
  293.     if( timedisplay )
  294.     {
  295.         timedisplay->counter = -1;
  296.     }
  297.     // reset mouse
  298.     pMouseCursor->Reset( 0 );
  299.     // reset player
  300.     pPlayer->Reset( 0 );
  301.  
  302.     // no version
  303.     engine_version = -1;
  304.  
  305.     levelfile.clear();
  306.  
  307.     // delete sprites at last
  308.     pSprite_Manager->Delete_All();
  309. }
  310.  
  311. void cLevel :: Save( void )
  312. {
  313.     pAudio->Play_Sound( "editor/save.ogg" );
  314.  
  315.     // check if old filename ending
  316.     if( levelfile.rfind( ".txt" ) != string::npos )
  317.     {
  318.         levelfile.erase( levelfile.rfind( ".txt" ) );
  319.         levelfile.insert( levelfile.length(), ".smclvl" );
  320.     }
  321.  
  322.     // use user level dir
  323.     if( levelfile.find( user_data_dir + USER_LEVEL_DIR + "/" ) == string::npos )
  324.     {
  325.         // erase old directory
  326.         levelfile = Get_Filename( levelfile, 0, 1 );
  327.         // set user directory
  328.         levelfile.insert( 0, user_data_dir + USER_LEVEL_DIR + "/" );
  329.     }
  330.  
  331.     ofstream file( levelfile.c_str(), ios::out | ios::trunc );
  332.  
  333.     if( !file )
  334.     {
  335.         debugdisplay->Set_Text( _("Couldn't save level ") + levelfile );
  336.         return;
  337.     }
  338.  
  339.     // xml info
  340.     file << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
  341.     // begin level
  342.     file << "<level>" << std::endl;
  343.  
  344.     // begin info
  345.     file << "\t<information>" << std::endl;
  346.         // game version
  347.         file << "\t\t<Property name=\"game_version\" value=\"" << smc_version << "\" />" << std::endl;
  348.         // engine version
  349.         file << "\t\t<Property name=\"engine_version\" value=\"" << level_engine_version << "\" />" << std::endl;
  350.         // time ( seconds since 1970 )
  351.         file << "\t\t<Property name=\"save_time\" value=\"" << time( NULL ) << "\" />" << std::endl;
  352.     // end info
  353.     file << "\t</information>" << std::endl;
  354.  
  355.     // begin settings
  356.     file << "\t<settings>" << std::endl;
  357.         // level author
  358.         file << "\t\t<Property name=\"lvl_author\" value=\"" << string_to_xml_string( author ) << "\" />" << std::endl;
  359.         // level version
  360.         file << "\t\t<Property name=\"lvl_version\" value=\"" << string_to_xml_string( version ) << "\" />" << std::endl;
  361.         // music
  362.         string music_file = Get_Musicfile( 1 );
  363.         file << "\t\t<Property name=\"lvl_music\" value=\"" << string_to_xml_string( music_file ) << "\" />" << std::endl;
  364.         // camera limits
  365.         file << "\t\t<Property name=\"cam_limit_x\" value=\"" << static_cast<int>(pLevel_Manager->camera->limit_rect.x) << "\" />" << std::endl;
  366.         file << "\t\t<Property name=\"cam_limit_y\" value=\"" << static_cast<int>(pLevel_Manager->camera->limit_rect.y) << "\" />" << std::endl;
  367.         file << "\t\t<Property name=\"cam_limit_w\" value=\"" << static_cast<int>(pLevel_Manager->camera->limit_rect.w) << "\" />" << std::endl;
  368.         file << "\t\t<Property name=\"cam_limit_h\" value=\"" << static_cast<int>(pLevel_Manager->camera->limit_rect.h) << "\" />" << std::endl;
  369.         // fixed camera horizontal velocity
  370.         file << "\t\t<Property name=\"cam_fixed_hor_vel\" value=\"" << pLevel_Manager->camera->fixed_hor_vel << "\" />" << std::endl;
  371.     // end settings
  372.     file << "\t</settings>" << std::endl;
  373.  
  374.     // backgrounds
  375.     for( vector<cBackground *>::iterator itr = background_manager->objects.begin(), itr_end = background_manager->objects.end(); itr != itr_end; ++itr )
  376.     {
  377.         (*itr)->Save_to_Stream( file );
  378.     }
  379.     // global effect
  380.     pGlobal_effect->Save_to_Stream( file );
  381.     // player
  382.     pPlayer->Save_to_Stream( file );
  383.     // objects
  384.     for( SpriteList::iterator itr = pSprite_Manager->objects.begin(), itr_end = pSprite_Manager->objects.end(); itr != itr_end; ++itr )
  385.     {
  386.         cSprite *obj = (*itr);
  387.  
  388.         // skip spawned and destroyed objects
  389.         if( obj->spawned || obj->destroy )
  390.         {
  391.             continue;
  392.         }
  393.  
  394.         // save to file stream
  395.         obj->Save_to_Stream( file );
  396.     }
  397.  
  398.     // end level
  399.     file << "</level>" << std::endl;
  400.     file.close();
  401.  
  402.     debugdisplay->Set_Text( _("Level ") + Get_Filename( data_file, 0, 0 ) + _(" saved") );
  403. }
  404.  
  405. void cLevel :: Delete( void )
  406. {
  407.     Delete_File( levelfile );
  408.  
  409.     Unload();
  410. }
  411.  
  412. void cLevel :: Update( void )
  413. {
  414.     if( delayed_unload )
  415.     {
  416.         Unload();
  417.         return;
  418.     }
  419.  
  420.     if( !next_levelfile.empty() )
  421.     {
  422.         Load( next_levelfile );
  423.     }
  424.  
  425.     // if leveleditor not active
  426.     if( !editor_level_enabled )
  427.     {
  428.         // backgrounds
  429.         for( vector<cBackground *>::iterator itr = background_manager->objects.begin(), itr_end = background_manager->objects.end(); itr != itr_end; ++itr )
  430.         {
  431.             (*itr)->Update();
  432.         }
  433.  
  434.         // objects
  435.         pSprite_Manager->Update_Items();
  436.  
  437.         // animations
  438.         pAnimation_Manager->Update();
  439.  
  440.         // global effect
  441.         pGlobal_effect->Update();
  442.     }
  443. }
  444.  
  445. void cLevel :: Draw_Layer1( LevelDrawType type /* = LVL_DRAW */ )
  446. {
  447.     // with background
  448.     if( type != LVL_DRAW_NO_BG )
  449.     {
  450.         for( vector<cBackground *>::iterator itr = background_manager->objects.begin(), itr_end = background_manager->objects.end(); itr != itr_end; ++itr )
  451.         {
  452.             (*itr)->Draw();
  453.         }
  454.     }
  455.  
  456.     // only background
  457.     if( type == LVL_DRAW_BG )
  458.     {
  459.         return;
  460.     }
  461.  
  462.     // Objects
  463.     pSprite_Manager->Draw_Items();
  464.     // Animations
  465.     pAnimation_Manager->Draw();
  466. }
  467.  
  468. void cLevel :: Draw_Layer2( LevelDrawType type /* = LVL_DRAW */ )
  469. {
  470.     // only background
  471.     if( type == LVL_DRAW_BG )
  472.     {
  473.         return;
  474.     }
  475.  
  476.     // global effect
  477.     if( !editor_level_enabled )
  478.     {
  479.         pGlobal_effect->Draw();
  480.     }
  481.  
  482.     // ghost
  483.     if( pPlayer->maryo_type == MARYO_GHOST )
  484.     {
  485.         // create request
  486.         cRectRequest *request = new cRectRequest();
  487.  
  488.         Color color = Color( 0.5f, 0.5f, 0.5f, 0.3f );
  489.         pVideo->Draw_Rect( 0, 0, static_cast<float>(game_res_w), static_cast<float>(game_res_h), 0.12f, &color, request );
  490.  
  491.         request->combine_type = GL_MODULATE;
  492.  
  493.         request->combine_col[0] = 0.9f;
  494.         request->combine_col[1] = 0.6f;
  495.         request->combine_col[2] = 0.8f;
  496.  
  497.  
  498.         // add request
  499.         pRenderer->Add( request );
  500.     }
  501. }
  502.  
  503. void cLevel :: Process_Input( void )
  504. {
  505.     // only non editor
  506.     if( !editor_level_enabled )
  507.     {
  508.         // none
  509.     }
  510. }
  511.  
  512. bool cLevel :: Key_Down( SDLKey key )
  513. {
  514.     // debug key F2
  515.     if( key == SDLK_F2 && game_debug && !editor_level_enabled )
  516.     {
  517.         pPlayer->Set_Type( MARYO_CAPE, 0 );
  518.     }
  519.     // debug key F3
  520.     else if( key == SDLK_F3 && !editor_level_enabled )
  521.     {
  522.         //pPlayer->GotoNextLevel();
  523.         //DrawEffect( HORIZONTAL_VERTICAL_FADE );
  524.         //pPlayer->Draw_Animation( MARYO_FIRE );
  525.  
  526.         cParticle_Emitter *anim = new cParticle_Emitter();
  527.         anim->Set_Emitter_Rect( pPlayer->posx + static_cast<float>( pPlayer->col_rect.w / 2 ), pPlayer->posy - 100, 10, 10 );
  528.         anim->Set_Emitter_Time_to_Live( -1 );
  529.         anim->Set_Emitter_Iteration_Interval( 5 );
  530.         anim->Set_Quota( 200 );
  531.         anim->Set_Image( pVideo->Get_Surface( "animation/particles/star.png" ) );
  532.         anim->Set_Time_to_Live( 3, 3 );
  533.         anim->Set_Fading_Alpha( 1 );
  534.         anim->Set_Speed( 1, 4 );
  535.         anim->Set_Scale( 0.5f );
  536.         anim->Set_Const_Rotation_Z( -5, 10 );
  537.         pAnimation_Manager->Add( anim );
  538.     }
  539.     // debug key F4
  540.     else if( key == SDLK_F4 )
  541.     {
  542.         Draw_Effect_Out( EFFECT_OUT_RANDOM_COLOR_BOOST );
  543.         //pPlayer->Get_Item( TYPE_MUSHROOM_DEFAULT );
  544.  
  545.         /*if( pGlobal_effect->type != GL_EFF_FALLING )
  546.         {
  547.             pGlobal_effect->Set_image( "animation/particles/rain.png" );
  548.             pGlobal_effect->Set_Type( GL_EFF_FALLING );
  549.             pGlobal_effect->Set_Lifetime_mod( 4 );
  550.             pGlobal_effect->Set_Scale( 0.5f, 0.5f );
  551.             pGlobal_effect->Set_Creation_Speed( 2 );
  552.             pGlobal_effect->Set_Speed( 13, 5 );
  553.             pGlobal_effect->Set_Direction( 90, 0 );
  554.             pGlobal_effect->Set_ConstRotationZ( 0, 0 );
  555.             pGlobal_effect->Init_Anim();
  556.         }*/
  557.     }
  558.     // Toggle leveleditor
  559.     else if( key == SDLK_F8 )
  560.     {
  561.         pLevel_Editor->Toggle();
  562.     }
  563.     // ## Game
  564.     // Shoot
  565.     else if( key == pPreferences->key_shoot && !editor_enabled )
  566.     {
  567.         pPlayer->Action_Shoot();
  568.     }
  569.     // Jump
  570.     else if( key == pPreferences->key_jump && !editor_enabled )
  571.     {
  572.         pPlayer->Action_Jump();
  573.     }
  574.     // Action
  575.     else if( key == pPreferences->key_action && !editor_enabled )
  576.     {
  577.         pPlayer->Action_Interact( INP_ACTION );
  578.     }
  579.     // Up
  580.     else if( key == pPreferences->key_up && !editor_enabled )
  581.     {
  582.         pPlayer->Action_Interact( INP_UP );
  583.     }
  584.     // Down
  585.     else if( key == pPreferences->key_down && !editor_enabled )
  586.     {
  587.         pPlayer->Action_Interact( INP_DOWN );
  588.     }
  589.     // Left
  590.     else if( key == pPreferences->key_left && !editor_enabled )
  591.     {
  592.         pPlayer->Action_Interact( INP_LEFT );
  593.     }
  594.     // Right
  595.     else if( key == pPreferences->key_right && !editor_enabled )
  596.     {
  597.         pPlayer->Action_Interact( INP_RIGHT );
  598.     }
  599.     // Request Item
  600.     else if( key == SDLK_RETURN && !editor_enabled )
  601.     {
  602.         pPlayer->Action_Interact( INP_ITEM );
  603.     }
  604.     // God Mode
  605.     else if( pKeyboard->keys[SDLK_g] && pKeyboard->keys[SDLK_o] && pKeyboard->keys[SDLK_d] && !editor_enabled )
  606.     {
  607.         if( pPlayer->godmode )
  608.         {
  609.             debugdisplay->Set_Text( "Funky God Mode disabled" );
  610.         }
  611.         else
  612.         {
  613.             debugdisplay->Set_Text( "Funky God Mode enabled" );
  614.         }
  615.  
  616.         pPlayer->godmode = !pPlayer->godmode;
  617.     }
  618.     // Set Small state
  619.     else if( pKeyboard->keys[SDLK_k] && pKeyboard->keys[SDLK_i] && pKeyboard->keys[SDLK_d] && !editor_enabled )
  620.     {
  621.         pPlayer->Set_Type( MARYO_SMALL, 0 );
  622.     }
  623.     // Exit
  624.     else if( key == SDLK_ESCAPE )
  625.     {
  626.         pPlayer->Action_Interact( INP_EXIT );
  627.     }
  628.     // ## editor
  629.     else if( pLevel_Editor->Key_Down( key ) )
  630.     {
  631.         // processed by the editor
  632.         return 1;
  633.     }
  634.     else
  635.     {
  636.         // not processed
  637.         return 0;
  638.     }
  639.  
  640.     // key got processed
  641.     return 1;
  642. }
  643.  
  644. bool cLevel :: Key_Up( SDLKey key )
  645. {
  646.     // only if not in Editor
  647.     if( editor_level_enabled )
  648.     {
  649.         return 0;
  650.     }
  651.  
  652.     // Interaction keys
  653.     if( key == pPreferences->key_right )
  654.     {
  655.         pPlayer->Action_Stop_Interact( INP_RIGHT );
  656.     }
  657.     else if( key == pPreferences->key_left )
  658.     {
  659.         pPlayer->Action_Stop_Interact( INP_LEFT );
  660.     }
  661.     else if( key == pPreferences->key_down )
  662.     {
  663.         pPlayer->Action_Stop_Interact( INP_DOWN );
  664.     }
  665.     else if( key == pPreferences->key_jump )
  666.     {
  667.         pPlayer->Action_Stop_Interact( INP_JUMP );
  668.     }
  669.     else if( key == pPreferences->key_shoot )
  670.     {
  671.         pPlayer->Action_Stop_Interact( INP_SHOOT );
  672.     }
  673.     else if( key == pPreferences->key_action )
  674.     {
  675.         pPlayer->Action_Stop_Interact( INP_ACTION );
  676.     }
  677.     else
  678.     {
  679.         // not processed
  680.         return 0;
  681.     }
  682.  
  683.  
  684.     // key got processed
  685.     return 1;
  686. }
  687.  
  688. bool cLevel :: Mouse_Down( Uint8 button )
  689. {
  690.     // ## editor
  691.     if( pLevel_Editor->Mouse_Down( button ) )
  692.     {
  693.         // processed by the editor
  694.         return 1;
  695.     }
  696.     else
  697.     {
  698.         // not processed
  699.         return 0;
  700.     }
  701.  
  702.     // button got processed
  703.     return 1;
  704. }
  705.  
  706. bool cLevel :: Mouse_Up( Uint8 button )
  707. {
  708.     // ## editor
  709.     if( pLevel_Editor->Mouse_Up( button ) )
  710.     {
  711.         // processed by the editor
  712.         return 1;
  713.     }
  714.     else
  715.     {
  716.         // not processed
  717.         return 0;
  718.     }
  719.  
  720.     // button got processed
  721.     return 1;
  722. }
  723.  
  724. bool cLevel :: Joy_Button_Down( Uint8 button )
  725. {
  726.     // Shoot
  727.     if( button == pPreferences->joy_button_shoot && !editor_enabled )
  728.     {
  729.         pPlayer->Action_Interact( INP_SHOOT );
  730.     }
  731.     // Jump
  732.     else if( button == pPreferences->joy_button_jump && !editor_enabled )
  733.     {
  734.         pPlayer->Action_Interact( INP_JUMP );
  735.     }
  736.     // Interaction keys
  737.     else if( button == pPreferences->joy_button_action && !editor_enabled )
  738.     {
  739.         pPlayer->Action_Interact( INP_ACTION );
  740.     }
  741.     // Request Itembox Item
  742.     else if( button == pPreferences->joy_button_item && !editor_enabled )
  743.     {
  744.         pPlayer->Action_Interact( INP_ITEM );
  745.     }
  746.     // Enter menu
  747.     else if( button == pPreferences->joy_button_exit )
  748.     {
  749.         pPlayer->Action_Interact( INP_EXIT );
  750.     }
  751.     else
  752.     {
  753.         // not processed
  754.         return 0;
  755.     }
  756.  
  757.     // key got processed
  758.     return 1;
  759. }
  760.  
  761. bool cLevel :: Joy_Button_Up( Uint8 button )
  762. {
  763.     // only if not in Editor
  764.     if( editor_level_enabled )
  765.     {
  766.         return 0;
  767.     }
  768.  
  769.     if( button == pPreferences->joy_button_jump )
  770.     {
  771.         pPlayer->Action_Stop_Interact( INP_JUMP );
  772.     }
  773.     else if( button == pPreferences->joy_button_shoot )
  774.     {
  775.         pPlayer->Action_Stop_Interact( INP_SHOOT );
  776.     }
  777.     else if( button == pPreferences->joy_button_action )
  778.     {
  779.         pPlayer->Action_Stop_Interact( INP_ACTION );
  780.     }
  781.     else
  782.     {
  783.         // not processed
  784.         return 0;
  785.     }
  786.  
  787.  
  788.     // key got processed
  789.     return 1;
  790. }
  791.  
  792. string cLevel :: Get_Musicfile( int with_dir /* = 2 */, bool with_end /* = 1 */ )
  793. {
  794.     string filename = musicfile;
  795.  
  796.     // erase whole directory
  797.     if( with_dir == 0 && filename.rfind( "/" ) != string::npos )
  798.     {
  799.         filename.erase( 0, filename.rfind( "/" ) + 1 );
  800.     }
  801.     // erase music directory
  802.     else if( with_dir == 1 && filename.find( DATA_DIR "/" GAME_MUSIC_DIR "/" ) != string::npos )
  803.     {
  804.         filename.erase( 0, strlen( DATA_DIR "/" GAME_MUSIC_DIR "/" ) );
  805.     }
  806.  
  807.     // erase file type
  808.     if( !with_end && filename.rfind( "." ) != string::npos )
  809.     {
  810.         filename.erase( filename.rfind( "." ) );
  811.     }
  812.  
  813.     return filename;
  814. }
  815.  
  816. void cLevel :: Set_Musicfile( string filename )
  817. {
  818.     if( filename.length() < 4 )
  819.     {
  820.         return;
  821.     }
  822.  
  823.     Convert_Path_Separators( filename );
  824.  
  825.     // add music dir
  826.     if( filename.find( DATA_DIR "/" GAME_MUSIC_DIR "/" ) == string::npos )
  827.     {
  828.         filename.insert( 0, DATA_DIR "/" GAME_MUSIC_DIR "/" );
  829.     }
  830.  
  831.     musicfile = filename;
  832.     // check if music is available
  833.     valid_music = File_Exists( filename );
  834. }
  835.  
  836. void cLevel :: Set_Levelfile( string filename, bool delete_old /* = 1 */ )
  837. {
  838.     // erase file type and directory
  839.     filename = Get_Filename( filename, 0, 0 );
  840.  
  841.     // if invalid
  842.     if( filename.length() < 2 )
  843.     {
  844.         return;
  845.     }
  846.  
  847.     // delete file with the old name
  848.     if( delete_old )
  849.     {
  850.         Delete_File( levelfile );
  851.     }
  852.  
  853.     Convert_Path_Separators( filename );
  854.  
  855.     // add level file type
  856.     if( filename.find( ".smclvl" ) == string::npos )
  857.     {
  858.         filename.insert( filename.length(), ".smclvl" );
  859.     }
  860.  
  861.     levelfile = filename;
  862.     data_file = filename;
  863.  
  864.     // add level dir
  865.     if( levelfile.find( user_data_dir + USER_LEVEL_DIR + "/" ) == string::npos )
  866.     {
  867.         levelfile.insert( 0, user_data_dir + USER_LEVEL_DIR + "/" );
  868.     }
  869.  
  870.     // save with new filename
  871.     Save();
  872. }
  873.  
  874. bool cLevel :: Get_Path( string &filename, bool check_only_user_dir /* = 0 */ )
  875. {
  876.     filename = Get_Filename( filename, 0, 0 );
  877.  
  878.     // user level directory as default
  879.     filename.insert( 0, user_data_dir + USER_LEVEL_DIR + "/" );
  880.     // use new file type as default
  881.     filename.insert( filename.length(), ".smclvl" );
  882.  
  883.     if( File_Exists( filename ) )
  884.     {
  885.         // found
  886.         return 1;
  887.     }
  888.  
  889.     // use old file type
  890.     filename.erase( filename.rfind( "." ) );
  891.     filename.insert( filename.length(), ".txt" );
  892.  
  893.     if( File_Exists( filename ) )
  894.     {
  895.         // found
  896.         return 1;
  897.     }
  898.  
  899.     if( !check_only_user_dir )
  900.     {
  901.         // use new file type
  902.         filename.erase( filename.rfind( "." ) );
  903.         filename.insert( filename.length(), ".smclvl" );
  904.  
  905.         // erase user level directory
  906.         filename.erase( 0, user_data_dir.length() + strlen( USER_LEVEL_DIR "/" ) );
  907.  
  908.         // game level directory
  909.         if( filename.find( DATA_DIR "/" GAME_LEVEL_DIR "/" ) == string::npos )
  910.         {
  911.             filename.insert( 0, DATA_DIR "/" GAME_LEVEL_DIR "/" );
  912.         }
  913.  
  914.         if( File_Exists( filename ) )
  915.         {
  916.             // found
  917.             return 1;
  918.         }
  919.  
  920.         // use old file type
  921.         filename.erase( filename.rfind( "." ) );
  922.         filename.insert( filename.length(), ".txt" );
  923.  
  924.         if( File_Exists( filename ) )
  925.         {
  926.             // found
  927.             return 1;
  928.         }
  929.     }
  930.  
  931.     // erase file type and directory
  932.     filename = Get_Filename( filename, 0, 0 );
  933.  
  934.     // not found
  935.     return 0;
  936. }
  937.  
  938. void cLevel :: Set_Author( string name )
  939. {
  940.     author = name;
  941. }
  942.  
  943. void cLevel :: Set_Version( string level_version )
  944. {
  945.     version = level_version;
  946. }
  947.  
  948. cLevel_Entry* cLevel :: Get_Entry( string name )
  949. {
  950.     if( name.empty() )
  951.     {
  952.         return NULL;
  953.     }
  954.  
  955.     // Search for entry
  956.     for( SpriteList::iterator itr = pSprite_Manager->objects.begin(), itr_end = pSprite_Manager->objects.end(); itr != itr_end; ++itr )
  957.     {
  958.         cSprite *obj = (*itr);
  959.  
  960.         if( obj->type != TYPE_LEVEL_ENTRY )
  961.         {
  962.             continue;
  963.         }
  964.  
  965.         cLevel_Entry *level_entry = static_cast<cLevel_Entry *>(obj);
  966.  
  967.         // found
  968.         if( level_entry->entry_name.compare( name ) == 0 )
  969.         {
  970.             return level_entry;
  971.         }
  972.     }
  973.  
  974.     return NULL;
  975. }
  976.  
  977. bool cLevel :: Is_Loaded( void )
  978. {
  979.     // if not loaded version is -1
  980.     if( engine_version >= 0 )
  981.     {
  982.         return 1;
  983.     }
  984.  
  985.     return 0;
  986. }
  987.  
  988. bool cLevel :: HandleMessage( string *parts, unsigned int count, unsigned int line )
  989. {
  990.     if( parts[0].compare( "Player" ) == 0 )
  991.     {
  992.         if( count != 3 )
  993.         {
  994.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  995.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 3 parameters" );
  996.             return 0; // error
  997.         }
  998.  
  999.         if( !is_valid_number( parts[1] ) )
  1000.         {
  1001.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1002.             printf( "%s is not a valid integer value\n", parts[1].c_str() );
  1003.             return 0; // error
  1004.         }
  1005.         if( !is_valid_number( parts[2] ) )
  1006.         {
  1007.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1008.             printf( "%s is not a valid integer value\n", parts[2].c_str() );
  1009.             return 0; // error
  1010.         }
  1011.  
  1012.         pPlayer->Set_Pos( static_cast<float>(string_to_int( parts[1] )), static_cast<float>(game_res_h) - static_cast<float>( string_to_int( parts[2] ) + pPlayer->start_image->h ), 1 );
  1013.     }
  1014.     else if( parts[0].compare( "author" ) == 0 )
  1015.     {
  1016.         if( count != 2 )
  1017.         {
  1018.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1019.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 2 parameters" );
  1020.             return 0; // error
  1021.         }
  1022.  
  1023.         author = parts[1];
  1024.     }
  1025.     else if( parts[0].compare( "version" ) == 0 )
  1026.     {
  1027.         if( count != 2 )
  1028.         {
  1029.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1030.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 2 parameters" );
  1031.             return 0; // error
  1032.         }
  1033.  
  1034.         version = parts[1];
  1035.     }
  1036.     /***************************************************************************/
  1037.     else if( parts[0].compare( "Music" ) == 0 )
  1038.     {
  1039.         if( count != 2 )
  1040.         {
  1041.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1042.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 2 parameters" );
  1043.             return 0; // error
  1044.         }
  1045.  
  1046.         if( parts[1].length() < 3 )
  1047.         {
  1048.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1049.             printf( "No valid Music file\n" );
  1050.             return 0;  // error
  1051.         }
  1052.  
  1053.         Set_Musicfile( parts[1] );
  1054.     }
  1055.     /***************************************************************************/
  1056.     else if( parts[0].compare( "Mod_Camera" ) == 0 )
  1057.     {
  1058.         // ignore
  1059.     }
  1060.     /***************************************************************************/
  1061.     else if( parts[0].compare( "Background_Color" ) == 0 ) // compatibility with old levels
  1062.     {
  1063.         Color color;
  1064.  
  1065.         if( Read_Color_Data( parts, count, line, color ) == 0 )
  1066.         {
  1067.             return 0;
  1068.         }
  1069.  
  1070.         background_manager->Get_Pointer(0)->Set_Color_1( color );
  1071.         background_manager->Get_Pointer(0)->Set_Color_2( color );
  1072.     }
  1073.     else if( parts[0].compare( "Background_color_1" ) == 0 ) // top background color
  1074.     {
  1075.         Color color;
  1076.  
  1077.         if( !Read_Color_Data( parts, count, line, color ) )
  1078.         {
  1079.             return 0;
  1080.         }
  1081.  
  1082.         background_manager->Get_Pointer(0)->Set_Color_1( color );
  1083.     }
  1084.     else if( parts[0].compare( "Background_color_2" ) == 0 ) // bottom background color
  1085.     {
  1086.         Color color;
  1087.  
  1088.         if( !Read_Color_Data( parts, count, line, color ) )
  1089.         {
  1090.             return 0;
  1091.         }
  1092.  
  1093.         background_manager->Get_Pointer(0)->Set_Color_2( color );
  1094.     }
  1095.     /***************************************************************************/
  1096.     else if( parts[0].find( "Background_image" ) == 0 && parts[0].length() <= 18 )
  1097.     {
  1098.         if( count < 2 || count > 6 )
  1099.         {
  1100.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1101.             printf( "%s %s\n", parts[0].c_str(), "needs 2-6 parameters" );
  1102.             return 0; // error
  1103.         }
  1104.  
  1105.         if( parts[1].length() < 3 )
  1106.         {
  1107.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1108.             printf( "Not a valid %s file\n", parts[0].c_str() );
  1109.             return 0;  // error
  1110.         }
  1111.  
  1112.         string filename;
  1113.  
  1114.         filename.reserve( parts[1].length() + 50 );
  1115.         filename = parts[1];
  1116.  
  1117.         if( filename.find( DATA_DIR "/" GAME_PIXMAPS_DIR "/" ) == string::npos )
  1118.         {
  1119.             filename.insert( 0, DATA_DIR "/" GAME_PIXMAPS_DIR "/" );
  1120.         }
  1121.  
  1122.         if( !File_Exists( filename ) )
  1123.         {
  1124.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1125.             printf( "%s file not found : %s\n", parts[0].c_str(), filename.c_str() );
  1126.  
  1127.             return 0; // error
  1128.         }
  1129.  
  1130.         cBackground *background = new cBackground();
  1131.         background->Set_Image( parts[1] );
  1132.  
  1133.         // type is given
  1134.         if( count > 2 )
  1135.         {
  1136.             unsigned int bg_type = string_to_int( parts[2] );
  1137.  
  1138.             if( bg_type < 0 || bg_type > 200 )
  1139.             {
  1140.                 printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1141.                 printf( "Not a valid Background image type ( %d )\n", bg_type );
  1142.                 return 0;  // error
  1143.             }
  1144.  
  1145.             background->Set_Type( (BackgroundType)bg_type );
  1146.  
  1147.  
  1148.         }
  1149.         // default type
  1150.         else
  1151.         {
  1152.             background->Set_Type( BG_IMG_BOTTOM );
  1153.         }
  1154.  
  1155.         // x speed is given
  1156.         if( count > 3 )
  1157.         {
  1158.             float speedx = string_to_float( parts[3] );
  1159.             float speedy = 1;
  1160.  
  1161.             // y speed is given
  1162.             if( count > 4 )
  1163.             {
  1164.                 speedy = string_to_float( parts[3] );
  1165.             }
  1166.  
  1167.             // set speed
  1168.             background->Set_Scroll_Speed( speedx, speedy );
  1169.         }
  1170.  
  1171.         // z position is given
  1172.         if( count > 5 )
  1173.         {
  1174.             background->Set_Pos_Z( string_to_float( parts[4] ) );
  1175.         }
  1176.  
  1177.         background_manager->Add( background );
  1178.     }
  1179.     /***************************************************************************/
  1180.     else if( parts[0].find( "Background_image_type" ) == 0 )
  1181.     {
  1182.         // ignore
  1183.     }
  1184.     /***************************************************************************/
  1185.     else if( parts[0].find( "global_effect" ) == 0 || parts[0].find( "ge_base" ) == 0 )
  1186.     {
  1187.         if( count < 3 )
  1188.         {
  1189.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1190.             printf( "%s %s\n", parts[0].c_str(), "needs 3 parameters" );
  1191.             return 0; // error
  1192.         }
  1193.  
  1194.         if( parts[2].length() < 3 )
  1195.         {
  1196.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1197.             printf( "Not a valid %s file\n", parts[0].c_str() );
  1198.             return 0;  // error
  1199.         }
  1200.  
  1201.         if( !is_valid_number( parts[1] ) )
  1202.         {
  1203.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1204.             printf( "%s is not a valid integer value\n", parts[1].c_str() );
  1205.             return 0; // error
  1206.         }
  1207.  
  1208.         string filename;
  1209.  
  1210.         filename.reserve( parts[2].length() + 50 );
  1211.         filename = parts[2];
  1212.  
  1213.         if( filename.find( DATA_DIR "/" GAME_PIXMAPS_DIR "/" ) == string::npos )
  1214.         {
  1215.             filename.insert( 0, DATA_DIR "/" GAME_PIXMAPS_DIR "/" );
  1216.         }
  1217.  
  1218.         if( !File_Exists( filename ) )
  1219.         {
  1220.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1221.             printf( "%s file not found : %s\n", parts[0].c_str(), filename.c_str() );
  1222.  
  1223.             return 0; // error
  1224.         }
  1225.  
  1226.         // remove pixmaps dir
  1227.         if( filename.find( DATA_DIR "/" GAME_PIXMAPS_DIR "/" ) == 0 )
  1228.         {
  1229.             filename.erase( 0, strlen( DATA_DIR "/" GAME_PIXMAPS_DIR "/" ) );
  1230.         }
  1231.  
  1232.         int effect_type = string_to_int( parts[1] );
  1233.  
  1234.         pGlobal_effect->Set_Type( (GlobalEffectType)effect_type );
  1235.         pGlobal_effect->Set_Image( filename );
  1236.     }
  1237.     /***************************************************************************/
  1238.     else if( parts[0].find( "ge_rect" ) == 0 )
  1239.     {
  1240.         pGlobal_effect->Set_Emitter_Rect( GL_rect( string_to_float( parts[1] ), string_to_float( parts[2] ), string_to_float( parts[3] ), string_to_float( parts[4] ) ) );
  1241.     }
  1242.     else if( parts[0].find( "ge_lifetime_mod" ) == 0 )
  1243.     {
  1244.         pGlobal_effect->Set_Time_to_Live( string_to_float( parts[1] ) * 0.3f );
  1245.     }
  1246.     else if( parts[0].find( "ge_creation_speed" ) == 0 )
  1247.     {
  1248.         pGlobal_effect->Set_Emitter_Iteration_Interval( ( 1 / string_to_float( parts[1] ) ) * 0.032f );
  1249.     }
  1250.     else if( parts[0].find( "ge_scale" ) == 0 )
  1251.     {
  1252.         pGlobal_effect->Set_Scale( string_to_float( parts[1] ), string_to_float( parts[2] ) );
  1253.     }
  1254.     else if( parts[0].find( "ge_speed" ) == 0 )
  1255.     {
  1256.         pGlobal_effect->Set_Speed( string_to_float( parts[1] ), string_to_float( parts[2] ) );
  1257.     }
  1258.     else if( parts[0].find( "ge_dir_range" ) == 0 )
  1259.     {
  1260.         pGlobal_effect->Set_Direction( string_to_float( parts[1] ), string_to_float( parts[2] ) );
  1261.     }
  1262.     else if( parts[0].find( "ge_const_rotz" ) == 0 )
  1263.     {
  1264.         pGlobal_effect->Set_Const_Rotation_Z( string_to_float( parts[1] ), string_to_float( parts[2] ) );
  1265.     }
  1266.     /***************************************************************************/
  1267.     else if( parts[0].compare( "Levelengine_version" ) == 0 )
  1268.     {
  1269.         if( count != 2 )
  1270.         {
  1271.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1272.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 2 parameters" );
  1273.             return 0; // error
  1274.         }
  1275.  
  1276.         if( !is_valid_number( parts[1] ) )
  1277.         {
  1278.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1279.             printf( "%s is not a valid integer value\n", parts[1].c_str() );
  1280.             return 0; // error
  1281.         }
  1282.  
  1283.         engine_version = static_cast<float>(string_to_int( parts[1] ));
  1284.     }
  1285.     /***************************************************************************/
  1286.     else if( parts[0].compare( "Sprite" ) == 0 || parts[0].compare( "ClimbSprite" ) == 0 )
  1287.     {
  1288.         if( count != 5 )
  1289.         {
  1290.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1291.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 5 parameters" );
  1292.             return 0; // error
  1293.         }
  1294.  
  1295.         // check if the image file exists
  1296.         string filename = parts[1];
  1297.  
  1298.         while( filename.find( "/" ) == 0 )
  1299.         {
  1300.             filename.erase( 0, 1 );
  1301.         }
  1302.  
  1303.         if( filename.find( DATA_DIR "/" GAME_PIXMAPS_DIR "/" ) == string::npos )
  1304.         {
  1305.             filename.insert( 0, DATA_DIR "/" GAME_PIXMAPS_DIR "/" );
  1306.         }
  1307.  
  1308.         string settings_file = filename;
  1309.         settings_file.erase( settings_file.rfind( "." ) + 1 );
  1310.         settings_file.insert( settings_file.rfind( "." ) + 1, "settings" );
  1311.  
  1312.         if( !File_Exists( filename ) && !File_Exists( settings_file ) )
  1313.         {
  1314.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1315.             printf( "file not found : %s\n", parts[1].c_str() );
  1316.             return 0; // error
  1317.         }
  1318.  
  1319.         if( !is_valid_number( parts[2] ) )
  1320.         {
  1321.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1322.             printf( "%s is not a valid integer value\n", parts[2].c_str() );
  1323.             return 0; // error
  1324.         }
  1325.         if( !is_valid_number( parts[3] ) )
  1326.         {
  1327.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1328.             printf( "%s is not a valid integer value\n", parts[3].c_str() );
  1329.             return 0; // error
  1330.         }
  1331.         if( !parts[4].compare( "MASSIVE" ) == 0 && !parts[4].compare( "PASSIVE" ) == 0 && !parts[4].compare( "FRONT_PASSIVE" ) == 0 && !parts[4].compare( "HALFMASSIVE" ) == 0 )
  1332.         {
  1333.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1334.             printf( "parameter five has to be MASSIVE, PASSIVE, or HALFMASSIVE\n" );
  1335.             return 0; // error
  1336.         }
  1337.  
  1338.         string getimage_path = filename;
  1339.         getimage_path.erase( 0, strlen( DATA_DIR "/" GAME_PIXMAPS_DIR "/" ) );
  1340.  
  1341.         GL_Surface *surface = pVideo->Get_Surface( getimage_path );
  1342.         int posx = string_to_int( parts[2] );
  1343.         int posy = game_res_h - string_to_int( parts[3] );
  1344.  
  1345.         // if image is obsolete show a warning
  1346.         if( surface->obsolete )
  1347.         {
  1348.             printf( "%s : line %d Warning :\n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1349.             printf( "using obsolete image : %s\nAt position x : %d, y : %d\n", getimage_path.c_str(), posx, posy );
  1350.         }
  1351.  
  1352.         cSprite *temp = new cSprite( surface, static_cast<float>(posx), static_cast<float>(posy) );
  1353.  
  1354.         if( parts[4].compare( "MASSIVE" ) == 0 )
  1355.         {
  1356.             temp->Set_Sprite_Type( TYPE_MASSIVE );
  1357.         }
  1358.         else if( parts[4].compare( "PASSIVE" ) == 0 )
  1359.         {
  1360.             temp->Set_Sprite_Type( TYPE_PASSIVE );
  1361.         }
  1362.         else if( parts[4].compare( "FRONT_PASSIVE" ) == 0 )
  1363.         {
  1364.             temp->Set_Sprite_Type( TYPE_FRONT_PASSIVE );
  1365.         }
  1366.         else if( parts[4].compare( "HALFMASSIVE" ) == 0 )
  1367.         {
  1368.             // Climbable
  1369.             if( parts[0].compare( "ClimbSprite" ) == 0 )
  1370.             {
  1371.                 temp->Set_Sprite_Type( TYPE_CLIMBABLE );
  1372.             }
  1373.             // Halfmassive
  1374.             else
  1375.             {
  1376.                 temp->Set_Sprite_Type( TYPE_HALFMASSIVE );
  1377.             }
  1378.         }
  1379.  
  1380.         pSprite_Manager->Add( temp );
  1381.     }
  1382.     /***************************************************************************/
  1383.     else if( parts[0].compare( "Enemy" ) == 0 )
  1384.     {
  1385.         if( count < 3 )
  1386.         {
  1387.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1388.             printf( "Error : %s %s\n", parts[0].c_str(), "needs more than 2 parameters" );
  1389.             return 0; // error
  1390.         }
  1391.  
  1392.         if( !is_valid_number( parts[2] ) )
  1393.         {
  1394.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1395.             printf( "%s is not a valid integer value\n", parts[2].c_str() );
  1396.             return 0; // error
  1397.         }
  1398.         if( !is_valid_number( parts[3] ) )
  1399.         {
  1400.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1401.             printf( "%s is not a valid integer value\n", parts[3].c_str() );
  1402.             return 0; // error
  1403.         }
  1404.  
  1405.         // Goomba changed to Gumba and since 1.5 changed to Furball
  1406.         if( parts[1].compare( "GOOMBA" ) == 0 )
  1407.         {
  1408.             /* 3 and 4 is a very old description
  1409.              * 5 is lower than V.0.98
  1410.             */
  1411.             if( !( count == 3 || count == 4 || count == 5 || count == 6 ) )
  1412.             {
  1413.                 printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1414.                 printf( "Error : %s %s\n", parts[1].c_str(), "needs 5 parameters" );
  1415.                 return 0; // error
  1416.             }
  1417.  
  1418.             if( count >= 5 ) // color support
  1419.             {
  1420.                 cFurball *temp = NULL;
  1421.                 DefaultColor color = (DefaultColor)string_to_int( parts[4] );
  1422.  
  1423.                 // correct old color types
  1424.                 if( count == 5 )
  1425.                 {
  1426.                     // Blue
  1427.                     if( color == 1 )
  1428.                     {
  1429.                         color = COL_BLUE;
  1430.                     }
  1431.                     // Brown
  1432.                     else
  1433.                     {
  1434.                         color = COL_BROWN;
  1435.                     }
  1436.                 }
  1437.  
  1438.                 temp = new cFurball( (float)string_to_int( parts[2] ), (float)( game_res_h - string_to_int( parts[3] ) ) );
  1439.                 temp->Set_Color( color );
  1440.  
  1441.                 // direction support
  1442.                 if( count >= 6 )
  1443.                 {
  1444.                     if( !is_valid_number( parts[5] ) )
  1445.                     {
  1446.                         printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1447.                         printf( "%s is not a valid integer value\n", parts[5].c_str() );
  1448.                         return 0; // error
  1449.                     }
  1450.  
  1451.                     ObjectDirection direction = DIR_RIGHT;
  1452.                     direction = (ObjectDirection)string_to_int( parts[5] );
  1453.  
  1454.                     if( direction == DIR_LEFT || direction == DIR_RIGHT )
  1455.                     {
  1456.                         temp->Set_Direction( direction );
  1457.                     }
  1458.                 }
  1459.  
  1460.                 if( temp )
  1461.                 {
  1462.                     pSprite_Manager->Add( static_cast<cMovingSprite *>(temp) );
  1463.                 }
  1464.             }
  1465.             // support for old levels ( lower than V.0.8 )
  1466.             else
  1467.             {
  1468.                 cFurball *temp = new cFurball( (float)string_to_int( parts[2] ), (float)( game_res_h - string_to_int( parts[3] ) ) );
  1469.                 pSprite_Manager->Add( static_cast<cMovingSprite *>(temp) );
  1470.             }
  1471.         }
  1472.         // Turtle
  1473.         // RTURTLE for old level support
  1474.         else if( parts[1].compare( "RTURTLE" ) == 0 || parts[1].compare( "TURTLE" ) == 0 )
  1475.         {
  1476.             if( count < 4 || count > 5 )
  1477.             {
  1478.                 printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1479.                 printf( "Error : %s %s\n", parts[1].c_str(), "needs 4-5 parameters" );
  1480.                 return 0; // error
  1481.             }
  1482.  
  1483.             ObjectDirection direction = DIR_RIGHT;
  1484.  
  1485.             // with direction
  1486.             if( count > 4 )
  1487.             {
  1488.                 direction = (ObjectDirection)string_to_int( parts[4] );
  1489.             }
  1490.  
  1491.             cTurtle *temp = new cTurtle( (float)string_to_int( parts[2] ), (float)( game_res_h - string_to_int( parts[3] ) ) );
  1492.             temp->Set_Direction( direction );
  1493.             pSprite_Manager->Add( static_cast<cMovingSprite *>(temp) );
  1494.         }
  1495.         // Jumping Piranha
  1496.         else if( parts[1].compare( "JPIRANHA" ) == 0 )
  1497.         {
  1498.             if( count < 4 || count > 7 )
  1499.             {
  1500.                 printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1501.                 printf( "Error : %s %s\n", parts[1].c_str(), "needs 4-7 parameters" );
  1502.                 return 0; // error
  1503.             }
  1504.  
  1505.             ObjectDirection direction = DIR_UP;
  1506.             float max_distance = 200;
  1507.             float speed = 5.8f;
  1508.  
  1509.             // with direction and max_distance
  1510.             if( count > 5 )
  1511.             {
  1512.                 if( !is_valid_number( parts[4] ) )
  1513.                 {
  1514.                     printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1515.                     printf( "%s is not a valid integer value\n", parts[4].c_str() );
  1516.                     return 0; // error
  1517.                 }
  1518.  
  1519.                 if( !is_valid_number( parts[5] ) )
  1520.                 {
  1521.                     printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1522.                     printf( "%s is not a valid integer value\n", parts[5].c_str() );
  1523.                     return 0; // error
  1524.                 }
  1525.  
  1526.                 direction = (ObjectDirection)string_to_int( parts[4] );
  1527.                 max_distance = (float)string_to_int( parts[5] );
  1528.  
  1529.                 // fix wrong values
  1530.                 if( max_distance <= 0 )
  1531.                 {
  1532.                     max_distance = 200;
  1533.                 }
  1534.             }
  1535.  
  1536.             // with speed
  1537.             if( count > 6 )
  1538.             {
  1539.                 speed = string_to_float( parts[6] );
  1540.             }
  1541.  
  1542.             cjPiranha *temp = new cjPiranha( (float)string_to_int( parts[2] ), (float)( game_res_h - string_to_int( parts[3] ) ) );
  1543.             temp->Set_Direction( direction );
  1544.             temp->Set_Max_Distance( max_distance );
  1545.             temp->Set_Speed( speed );
  1546.             pSprite_Manager->Add( static_cast<cMovingSprite *>(temp) );
  1547.         }
  1548.         // Rokko
  1549.         // BANZAI_BILL was the old name
  1550.         else if( parts[1].compare( "ROKKO" ) == 0 || parts[1].compare( "BANZAI_BILL" ) == 0 )
  1551.         {
  1552.             if( count < 5 || count > 6 )
  1553.             {
  1554.                 printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1555.                 printf( "Line %d, error : %s %s\n", line, parts[1].c_str(), "needs 5-6 parameters" );
  1556.                 return 0; // error
  1557.             }
  1558.  
  1559.             float speed = 8.5f;
  1560.  
  1561.             // with speed
  1562.             if( count > 5 )
  1563.             {
  1564.                 speed = string_to_float( parts[5] );
  1565.             }
  1566.  
  1567.             cRokko *temp = new cRokko( (float)string_to_int( parts[2] ), (float)( game_res_h - string_to_int( parts[3] ) ) );
  1568.             temp->Set_Direction( (ObjectDirection)string_to_int( parts[4] ) );
  1569.             temp->Set_Speed( speed );
  1570.             pSprite_Manager->Add( static_cast<cMovingSprite *>(temp) );
  1571.         }
  1572.         // Rex and since 1.5 changed to Krush
  1573.         else if( parts[1].compare( "REX" ) == 0 )
  1574.         {
  1575.             if( count < 4 || count > 5 )
  1576.             {
  1577.                 printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1578.                 printf( "Line %d, error : %s %s\n", line, parts[1].c_str(), "needs 4-5 parameters" );
  1579.                 return 0; // error
  1580.             }
  1581.  
  1582.             ObjectDirection direction = DIR_RIGHT;
  1583.  
  1584.             // with direction
  1585.             if( count > 4 )
  1586.             {
  1587.                 direction = (ObjectDirection)string_to_int( parts[4] );
  1588.             }
  1589.  
  1590.             cKrush *temp = new cKrush( (float)string_to_int( parts[2] ), (float)( game_res_h - string_to_int( parts[3] ) ) );
  1591.             temp->Set_Direction( direction );
  1592.             pSprite_Manager->Add( static_cast<cMovingSprite *>(temp) );
  1593.         }
  1594.         // Thromp
  1595.         // Thwomp was the old name
  1596.         else if( parts[1].compare( "THROMP" ) == 0 || parts[1].compare( "THWOMP" ) == 0 )
  1597.         {
  1598.             if( count < 6 || count > 7 )
  1599.             {
  1600.                 printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1601.                 printf( "Error : %s %s\n", parts[1].c_str(), "needs 6-7 parameters" );
  1602.                 return 0; // error
  1603.             }
  1604.  
  1605.             if( !is_valid_number( parts[4] ) )
  1606.             {
  1607.                 printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1608.                 printf( "%s is not a valid integer value\n", parts[4].c_str() );
  1609.                 return 0; // error
  1610.             }
  1611.  
  1612.             if( !is_valid_number( parts[5] ) )
  1613.             {
  1614.                 printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1615.                 printf( "%s is not a valid integer value\n", parts[5].c_str() );
  1616.                 return 0; // error
  1617.             }
  1618.  
  1619.             ObjectDirection direction = (ObjectDirection)string_to_int( parts[4] );
  1620.             int max_distance = string_to_int( parts[5] );
  1621.             float speed = 7;
  1622.  
  1623.             // fix wrong values
  1624.             if( max_distance <= 0 )
  1625.             {
  1626.                 max_distance = 200;
  1627.             }
  1628.  
  1629.             // with speed
  1630.             if( count > 6 )
  1631.             {
  1632.                 speed = string_to_float( parts[6] );
  1633.             }
  1634.  
  1635.             cThromp *temp = new cThromp( (float)string_to_int( parts[2] ), (float)( game_res_h - string_to_int( parts[3] ) ) );
  1636.             temp->Set_Direction( direction );
  1637.             temp->Set_Max_Distance( static_cast<float>(max_distance) );
  1638.             temp->Set_Speed( speed );
  1639.  
  1640.             pSprite_Manager->Add( static_cast<cMovingSprite *>(temp) );
  1641.         }
  1642.         // Eato
  1643.         else if( parts[1].compare( "EATO" ) == 0 )
  1644.         {
  1645.             if( count != 5 )
  1646.             {
  1647.                 printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1648.                 printf( "Error : %s %s\n", parts[1].c_str(), "needs 5 parameters" );
  1649.                 return 0; // error
  1650.             }
  1651.  
  1652.             if( !is_valid_number( parts[4] ) )
  1653.             {
  1654.                 printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1655.                 printf( "%s is not a valid integer value\n", parts[4].c_str() );
  1656.                 return 0; // error
  1657.             }
  1658.  
  1659.             ObjectDirection direction = (ObjectDirection)string_to_int( parts[4] );
  1660.  
  1661.             cEato *temp = new cEato( (float)string_to_int( parts[2] ), (float)( game_res_h - string_to_int( parts[3] ) ) );
  1662.             temp->Set_Direction( direction );
  1663.             pSprite_Manager->Add( static_cast<cMovingSprite *>(temp) );
  1664.         }
  1665.         // Gee
  1666.         else if( parts[1].compare( "GEE" ) == 0 )
  1667.         {
  1668.             if( count < 6 || count > 7 )
  1669.             {
  1670.                 printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1671.                 printf( "Error : %s %s\n", parts[1].c_str(), "needs 6-7 parameters" );
  1672.                 return 0; // error
  1673.             }
  1674.  
  1675.             if( !is_valid_number( parts[4] ) )
  1676.             {
  1677.                 printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1678.                 printf( "%s is not a valid integer value\n", parts[4].c_str() );
  1679.                 return 0; // error
  1680.             }
  1681.  
  1682.             if( !is_valid_number( parts[5] ) )
  1683.             {
  1684.                 printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1685.                 printf( "%s is not a valid integer value\n", parts[5].c_str() );
  1686.                 return 0; // error
  1687.             }
  1688.  
  1689.             ObjectDirection direction = (ObjectDirection)string_to_int( parts[4] );
  1690.             DefaultColor color = COL_YELLOW;
  1691.             unsigned int max_distance = 400;
  1692.  
  1693.             // convert old gee type to color
  1694.             unsigned int gtype = string_to_int( parts[5] );
  1695.  
  1696.             if( gtype == 1 )
  1697.             {
  1698.                 color = COL_YELLOW;
  1699.             }
  1700.             else if( gtype == 2 )
  1701.             {
  1702.                 color = COL_RED;
  1703.             }
  1704.             else if( gtype == 3 )
  1705.             {
  1706.                 color = COL_GREEN;
  1707.             }
  1708.  
  1709.             // with max distance
  1710.             if( count > 6 )
  1711.             {
  1712.                 max_distance = string_to_int( parts[6] );
  1713.             }
  1714.  
  1715.             cGee *temp = new cGee( (float)string_to_int( parts[2] ), (float)( game_res_h - string_to_int( parts[3] ) ) );
  1716.             temp->Set_Direction( direction );
  1717.             temp->Set_Max_Distance( max_distance );
  1718.             temp->Set_Color( color );
  1719.             pSprite_Manager->Add( static_cast<cMovingSprite *>(temp) );
  1720.         }
  1721.         else
  1722.         {
  1723.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1724.             printf( "Line %d, error : %s %s\n", line, parts[1].c_str(), "Unknown Enemy type" );
  1725.             return 0; // error
  1726.         }
  1727.     }
  1728.     /***************************************************************************/
  1729.     else if( parts[0].compare( "Goldpiece" ) == 0 )
  1730.     {
  1731.         if( count < 3 || count > 4 )
  1732.         {
  1733.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1734.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 3-4 parameters" );
  1735.             return 0; // error
  1736.         }
  1737.  
  1738.         if( !is_valid_number( parts[1] ) )
  1739.         {
  1740.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1741.             printf( "%s is not a valid integer value\n", parts[1].c_str() );
  1742.             return 0; // error
  1743.         }
  1744.  
  1745.         if( !is_valid_number( parts[2] ) )
  1746.         {
  1747.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1748.             printf( "%s is not a valid integer value\n", parts[2].c_str() );
  1749.             return 0; // error
  1750.         }
  1751.  
  1752.         DefaultColor color = COL_YELLOW;
  1753.  
  1754.         // with color information
  1755.         if( count > 3 )
  1756.         {
  1757.             if( !is_valid_number( parts[3] ) )
  1758.             {
  1759.                 printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1760.                 printf( "%s is not a valid integer value\n", parts[3].c_str() );
  1761.                 return 0; // error
  1762.             }
  1763.  
  1764.             color = (DefaultColor)string_to_int( parts[3] );
  1765.         }
  1766.  
  1767.         cGoldpiece *temp = new cGoldpiece( (float)string_to_int( parts[1] ), (float)( game_res_h - string_to_int( parts[2] ) ) );
  1768.         temp->Set_Gold_Color( color );
  1769.         pSprite_Manager->Add( static_cast<cMovingSprite *>(temp) );
  1770.     }
  1771.     /***************************************************************************/
  1772.     else if( parts[0].compare( "Moon" ) == 0 )
  1773.     {
  1774.         if( count != 3 )
  1775.         {
  1776.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1777.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 3 parameters" );
  1778.             return 0; // error
  1779.         }
  1780.  
  1781.         if( !is_valid_number( parts[1] ) )
  1782.         {
  1783.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1784.             printf( "%s is not a valid integer value\n", parts[1].c_str() );
  1785.             return 0; // error
  1786.         }
  1787.  
  1788.         if( !is_valid_number( parts[2] ) )
  1789.         {
  1790.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1791.             printf( "%s is not a valid integer value\n", parts[2].c_str() );
  1792.             return 0; // error
  1793.         }
  1794.  
  1795.         cMoon *temp = new cMoon( (float)string_to_int( parts[1] ), (float)( game_res_h - string_to_int( parts[2] ) ) );
  1796.         pSprite_Manager->Add( static_cast<cMovingSprite *>(temp) );
  1797.     }
  1798.     /***************************************************************************/
  1799.     else if( parts[0].compare( "Levelexit" ) == 0 )
  1800.     {
  1801.         if( count < 3 || count > 5 )
  1802.         {
  1803.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1804.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 3-5 parameters" );
  1805.             return 0; // error
  1806.         }
  1807.  
  1808.         if( !is_valid_number( parts[1] ) )
  1809.         {
  1810.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1811.             printf( "%s is not a valid integer value\n", parts[1].c_str() );
  1812.             return 0; // error
  1813.         }
  1814.         if( !is_valid_number( parts[2] ) )
  1815.         {
  1816.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1817.             printf( "%s is not a valid integer value\n", parts[2].c_str() );
  1818.             return 0; // error
  1819.         }
  1820.  
  1821.         cLevel_Exit *temp = NULL;
  1822.  
  1823.         // with type and level
  1824.         if( count == 4 || count == 5 )
  1825.         {
  1826.             if( !is_valid_number( parts[3] ) )
  1827.             {
  1828.                 printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1829.                 printf( "%s is not a valid integer value\n", parts[2].c_str() );
  1830.                 return 0; // error
  1831.             }
  1832.  
  1833.             temp = new cLevel_Exit( (float)string_to_int( parts[1] ), (float)( game_res_h - string_to_int( parts[2] ) ) );
  1834.  
  1835.             // type
  1836.             temp->Set_Type( (Level_Exit_type)string_to_int( parts[3] ) );
  1837.  
  1838.             // with a given level
  1839.             if( count == 5 )
  1840.             {
  1841.                 temp->Set_Level( parts[4] );
  1842.             }
  1843.         }
  1844.         // older level support
  1845.         else
  1846.         {
  1847.             // add a door sprite
  1848.             cMovingSprite *door_sprite = new cMovingSprite( pVideo->Get_Surface( "game/level/door_yellow_1.png" ), (float)string_to_int( parts[1] ), (float)( game_res_h - string_to_int( parts[2] ) ) );
  1849.             door_sprite->Set_Sprite_Type( TYPE_PASSIVE );
  1850.             pSprite_Manager->Add( door_sprite );
  1851.             // add the levelexit
  1852.             temp = new cLevel_Exit( (float)( string_to_int( parts[1] ) + 13 ), (float)( game_res_h - string_to_int( parts[2] ) + 60 ) );
  1853.         }
  1854.  
  1855.         pSprite_Manager->Add( static_cast<cMovingSprite *>(temp) );
  1856.     }
  1857.     /***************************************************************************/
  1858.     else if( parts[0].compare( "BonusBox" ) == 0 )
  1859.     {
  1860.         if( !( count == 3 || count == 4 ) )
  1861.         {
  1862.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1863.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 3-4 parameters" );
  1864.             return 0; // error
  1865.         }
  1866.  
  1867.         // old level support
  1868.         if( count == 3 )
  1869.         {
  1870.             if( !is_valid_number( parts[1] ) )
  1871.             {
  1872.                 printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1873.                 printf( "%s is not a valid integer value\n", parts[1].c_str() );
  1874.                 return 0; // error
  1875.             }
  1876.             if( !is_valid_number( parts[2] ) )
  1877.             {
  1878.                 printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1879.                 printf( "%s is not a valid integer value\n", parts[2].c_str() );
  1880.                 return 0; // error
  1881.             }
  1882.  
  1883.             cBonusBox *temp = new cBonusBox( (float)string_to_int( parts[1] ), (float)( game_res_h - string_to_int( parts[2] ) ) );
  1884.             pSprite_Manager->Add( static_cast<cMovingSprite *>(temp) );
  1885.         }
  1886.         else if( count == 4 )
  1887.         {
  1888.             if( !is_valid_number( parts[1] ) )
  1889.             {
  1890.                 printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1891.                 printf( "%s is not a valid integer value\n", parts[1].c_str() );
  1892.                 return 0; // error
  1893.             }
  1894.             if ( !is_valid_number( parts[2] ) )
  1895.             {
  1896.                 printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1897.                 printf( "%s is not a valid integer value\n", parts[2].c_str() );
  1898.                 return 0; // error
  1899.             }
  1900.  
  1901.             cBonusBox *temp = new cBonusBox( (float)string_to_int( parts[1] ), (float)( game_res_h - string_to_int( parts[2] ) ) );
  1902.  
  1903.             // Auto Mushroom or Fireplant
  1904.             if( parts[3].compare( "AUTO" ) == 0 )
  1905.             {
  1906.                 temp->Set_Bonus_Type( TYPE_FIREPLANT );
  1907.             }
  1908.             // Life Mushroom
  1909.             else if( parts[3].compare( "LIFE" ) == 0 )
  1910.             {
  1911.                  temp->Set_Bonus_Type( TYPE_MUSHROOM_LIVE_1 );
  1912.             }
  1913.             // Jumping Star
  1914.             else if( parts[3].compare( "STAR" ) == 0 )
  1915.             {
  1916.                  temp->Set_Bonus_Type( TYPE_JSTAR );
  1917.             }
  1918.             // unknown Bonus item
  1919.             else
  1920.             {
  1921.                 delete temp;
  1922.                 printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1923.                 printf( "Bonusbox type Error %s\n", parts[3].c_str() );
  1924.                 return 0; // error
  1925.             }
  1926.  
  1927.             pSprite_Manager->Add( static_cast<cMovingSprite *>(temp) );
  1928.         }
  1929.         else
  1930.         {
  1931.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1932.             printf( "Bonusbox count Error %d\n", count );
  1933.             return 0; // error
  1934.         }
  1935.     }
  1936.     /***************************************************************************/
  1937.     else if( parts[0].compare( "GoldBox" ) == 0 )
  1938.     {
  1939.         if( count < 3 || count > 5 )
  1940.         {
  1941.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1942.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 3-5 parameters" );
  1943.             return 0; // error
  1944.         }
  1945.  
  1946.         if( !is_valid_number( parts[1] ) )
  1947.         {
  1948.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1949.             printf( "%s is not a valid integer value\n", parts[1].c_str() );
  1950.             return 0; // error
  1951.         }
  1952.  
  1953.         if( !is_valid_number( parts[2] ) )
  1954.         {
  1955.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1956.             printf( "%s is not a valid integer value\n", parts[2].c_str() );
  1957.             return 0; // error
  1958.         }
  1959.  
  1960.         DefaultColor color = COL_YELLOW;
  1961.  
  1962.         // with color information
  1963.         if( count > 3 )
  1964.         {
  1965.             if( !is_valid_number( parts[3] ) )
  1966.             {
  1967.                 printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1968.                 printf( "%s is not a valid integer value\n", parts[3].c_str() );
  1969.                 return 0; // error
  1970.             }
  1971.  
  1972.             color = (DefaultColor)string_to_int( parts[3] );
  1973.         }
  1974.  
  1975.         cBonusBox *temp = new cBonusBox( (float)string_to_int( parts[1] ), (float)( game_res_h - string_to_int( parts[2] ) ) );
  1976.         temp->Set_Animation( "Default" );
  1977.         temp->Set_Bonus_Type( TYPE_GOLDPIECE );
  1978.         temp->Set_Goldcolor( color );
  1979.         pSprite_Manager->Add( static_cast<cMovingSprite *>(temp) );
  1980.  
  1981.         // with useable times information
  1982.         if( count > 4 )
  1983.         {
  1984.             if( !is_valid_number( parts[4] ) )
  1985.             {
  1986.                 printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  1987.                 printf( "%s is not a valid integer value\n", parts[4].c_str() );
  1988.                 return 0; // error
  1989.             }
  1990.  
  1991.             temp->Set_Useable_Count( string_to_int( parts[4] ), 1 );
  1992.         }
  1993.     }
  1994.     /***************************************************************************/
  1995.     else if( parts[0].compare( "SpinBox" ) == 0 )
  1996.     {
  1997.         if( count != 3 )
  1998.         {
  1999.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  2000.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 3 parameters" );
  2001.             return 0; // error
  2002.         }
  2003.  
  2004.         if( !is_valid_number( parts[1] ) )
  2005.         {
  2006.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  2007.             printf( "%s is not a valid integer value\n", parts[1].c_str() );
  2008.             return 0; // error
  2009.         }
  2010.  
  2011.         if( !is_valid_number( parts[2] ) )
  2012.         {
  2013.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  2014.             printf( "%s is not a valid integer value\n", parts[2].c_str() );
  2015.             return 0; // error
  2016.         }
  2017.  
  2018.         cSpinBox *temp = new cSpinBox( (float)string_to_int( parts[1] ), (float)( game_res_h - string_to_int( parts[2] ) ) );
  2019.         pSprite_Manager->Add( static_cast<cMovingSprite *>(temp) );
  2020.     }
  2021.     /***************************************************************************/
  2022.     else if( parts[0].compare( "Cloud" ) == 0 )
  2023.     {
  2024.         if( count < 3 || count > 5 )
  2025.         {
  2026.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  2027.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 3-5 parameters" );
  2028.             return 0; // error
  2029.         }
  2030.  
  2031.         if( !is_valid_number( parts[1] ) )
  2032.         {
  2033.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  2034.             printf( "%s is not a valid integer value\n", parts[1].c_str() );
  2035.             return 0; // error
  2036.         }
  2037.  
  2038.         if( !is_valid_number( parts[2] ) )
  2039.         {
  2040.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  2041.             printf( "%s is not a valid integer value\n", parts[2].c_str() );
  2042.             return 0; // error
  2043.         }
  2044.  
  2045.         // convert to halfmassive
  2046.         cMovingSprite *temp = new cMovingSprite( pVideo->Get_Surface( "clouds/default_1/1_middle.png" ), (float)string_to_int( parts[1] ), (float)( game_res_h - string_to_int( parts[2] ) ) );
  2047.         temp->Set_Sprite_Type( TYPE_HALFMASSIVE );
  2048.  
  2049.         pSprite_Manager->Add( temp );
  2050.     }
  2051.     /***************************************************************************/
  2052.     else if( parts[0].compare( "EnemyStopper" ) == 0 )
  2053.     {
  2054.         if( count != 3 )
  2055.         {
  2056.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  2057.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 3 parameters" );
  2058.             return 0; // error
  2059.         }
  2060.         if( !is_valid_number( parts[1] ) )
  2061.         {
  2062.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  2063.             printf( "%s is not a valid integer value\n", parts[1].c_str() );
  2064.             return 0; // error
  2065.         }
  2066.         if( !is_valid_number( parts[2] ) )
  2067.         {
  2068.             printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  2069.             printf( "%s is not a valid integer value\n", parts[2].c_str() );
  2070.             return 0; // error
  2071.         }
  2072.  
  2073.         cEnemyStopper *temp = new cEnemyStopper( (float)string_to_int( parts[1] ), (float)( game_res_h - string_to_int( parts[2] ) ) );
  2074.         pSprite_Manager->Add( static_cast<cMovingSprite *>(temp) );
  2075.     }
  2076.     /***************************************************************************/
  2077.     else if( parts[0].compare( "movingplatform" ) == 0 )
  2078.     {
  2079.         if( count < 10 || count > 10 )
  2080.         {
  2081.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  2082.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 10 parameters" );
  2083.             return 0; // error
  2084.         }
  2085.  
  2086.         cMoving_Platform *temp = new cMoving_Platform( (float)string_to_int( parts[1] ), (float)(game_res_h - string_to_int( parts[2] )) );
  2087.  
  2088.         if( string_to_int( parts[3] ) == 1 )
  2089.         {
  2090.             temp->Set_Direction( DIR_DOWN );
  2091.         }
  2092.         else
  2093.         {
  2094.             temp->Set_Direction( DIR_RIGHT );
  2095.         }
  2096.  
  2097.         temp->Set_Max_Distance( string_to_int( parts[4] ) );
  2098.         temp->Set_Speed( string_to_float( parts[5] ) );
  2099.         temp->Set_Middle_Count( string_to_int( parts[6] ) );
  2100.  
  2101.         temp->Set_Image_Top_Left( pVideo->Get_Surface( parts[7] ) );
  2102.         temp->Set_Image_Top_Middle( pVideo->Get_Surface( parts[8] ) );
  2103.         temp->Set_Image_Top_Right( pVideo->Get_Surface( parts[9] ) );
  2104.  
  2105.         pSprite_Manager->Add( static_cast<cMovingSprite *>(temp) );
  2106.     }
  2107.     /***************************************************************************/
  2108.     else if( parts[0].compare( "camera_limits" ) == 0 )
  2109.     {
  2110.         if( count < 5 || count > 5 )
  2111.         {
  2112.             printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  2113.             printf( "Error : %s %s\n", parts[0].c_str(), "needs 5 parameters" );
  2114.             return 0; // error
  2115.         }
  2116.  
  2117.         pLevel_Manager->camera->Set_Limits( GL_rect( (float)string_to_int( parts[1] ), (float)string_to_int( parts[2] ), (float)string_to_int( parts[3] ), (float)string_to_int( parts[4] ) ) );
  2118.     }
  2119.     /***************************************************************************/
  2120.     else
  2121.     {
  2122.         printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  2123.         printf( "Unknown Command : %s\n", parts[0].c_str() );
  2124.         return 0; // error
  2125.     }
  2126.  
  2127.     // Successful
  2128.     return 1;
  2129. }
  2130.  
  2131. bool cLevel :: Read_Color_Data( string *parts, unsigned int count, unsigned int line, Color &color )
  2132. {
  2133.     if( count != 4 )
  2134.     {
  2135.         printf( "%s : line %d Error : \n", Get_Filename( data_file, 0, 0 ).c_str(), line );
  2136.         printf( "Error : %s %s\n", parts[0].c_str(), "needs 4 parameters" );
  2137.         return 0; // error
  2138.     }
  2139.  
  2140.     if( !is_valid_number( parts[1] ) )
  2141.     {
  2142.         printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  2143.         printf( "%s is not a valid integer value\n", parts[1].c_str() );
  2144.         return 0; // error
  2145.     }
  2146.     if( !is_valid_number( parts[2] ) )
  2147.     {
  2148.         printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  2149.         printf( "%s is not a valid integer value\n", parts[2].c_str() );
  2150.         return 0; // error
  2151.     }
  2152.     if( !is_valid_number( parts[3] ) )
  2153.     {
  2154.         printf( "%s : line %d Error : ", Get_Filename( data_file, 0, 0 ).c_str(), line );
  2155.         printf( "%s is not a valid integer value\n", parts[3].c_str() );
  2156.         return 0; // error
  2157.     }
  2158.  
  2159.     int background_red = string_to_int( parts[1] );
  2160.     int background_green = string_to_int( parts[2] );
  2161.     int background_blue = string_to_int( parts[3] );
  2162.  
  2163.     if( background_red < 0 || background_red > 255 )
  2164.     {
  2165.         printf( "Warning : Background color red is not between 0 - 255\n" );
  2166.         background_red = 0;
  2167.     }
  2168.     else if( background_green < 0 || background_green > 255 )
  2169.     {
  2170.         printf( "Warning : Background color green is not between 0 - 255\n" );
  2171.         background_green = 0;
  2172.     }
  2173.     else if( background_blue < 0 || background_blue > 255 )
  2174.     {
  2175.         printf( "Warning : Background color blue is not between 0 - 255\n" );
  2176.         background_blue = 0;
  2177.     }
  2178.  
  2179.     color.red = background_red;
  2180.     color.green = background_green;
  2181.     color.blue = background_blue;
  2182.  
  2183.     return 1;  // success
  2184. }
  2185.  
  2186. // XML element start
  2187. void cLevel :: elementStart( const CEGUI::String &element, const CEGUI::XMLAttributes &attributes )
  2188. {
  2189.     // Property/Item/Tag of an Element
  2190.     if( element == "Property" )
  2191.     {
  2192.         xml_attributes.add( attributes.getValueAsString( "name" ), attributes.getValueAsString( "value" ) );
  2193.     }
  2194. }
  2195.  
  2196. // XML element end
  2197. void cLevel :: elementEnd( const CEGUI::String &element )
  2198. {
  2199.     if( element != "Property" )
  2200.     {
  2201.         if( element == "information" )
  2202.         {
  2203.             engine_version = xml_attributes.getValueAsFloat( "engine_version" );
  2204.             last_saved = xml_attributes.getValueAsInteger( "save_time" );
  2205.         }
  2206.         else if( element == "settings" )
  2207.         {
  2208.             // Author
  2209.             author = xml_attributes.getValueAsString( "lvl_author" ).c_str();
  2210.             // Version
  2211.             version = xml_attributes.getValueAsString( "lvl_version" ).c_str();
  2212.             // Music
  2213.             Set_Musicfile( xml_attributes.getValueAsString( "lvl_music" ).c_str() );
  2214.             // Camera Limits
  2215.             pLevel_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" )) ) );
  2216.             // fixed camera horizontal velocity
  2217.             pLevel_Manager->camera->fixed_hor_vel = xml_attributes.getValueAsFloat( "cam_fixed_hor_vel" );
  2218.         }
  2219.         else if( element == "background" )
  2220.         {
  2221.             BackgroundType bg_type = static_cast<BackgroundType>(xml_attributes.getValueAsInteger( "type" ));
  2222.  
  2223.             // use gradient background
  2224.             if( bg_type == BG_GR_HOR || bg_type == BG_GR_VER )
  2225.             {
  2226.                 background_manager->Get_Pointer(0)->Create_from_Stream( xml_attributes );
  2227.             }
  2228.             // default background
  2229.             else
  2230.             {
  2231.                 background_manager->Add( new cBackground( xml_attributes ) );
  2232.             }
  2233.         }
  2234.         else if( element == "global_effect" )
  2235.         {
  2236.             pGlobal_effect->Create_from_Stream( xml_attributes );
  2237.         }
  2238.         else if( element == "player" )
  2239.         {
  2240.             pPlayer->Create_from_Stream( xml_attributes );
  2241.         }
  2242.         else
  2243.         {
  2244.             // get Level object
  2245.             cSprite *object = Get_Level_Object( element, xml_attributes, engine_version );
  2246.             
  2247.             // valid
  2248.             if( object )
  2249.             {
  2250.                 pSprite_Manager->Add( object );
  2251.             }
  2252.             else if( element == "level" )
  2253.             {
  2254.                 // ignore
  2255.             }
  2256.             else if( element.length() )
  2257.             {
  2258.                 printf( "Warning : Level Unknown element : %s\n", element.c_str() );
  2259.             }
  2260.         }
  2261.  
  2262.         // clear
  2263.         xml_attributes = CEGUI::XMLAttributes();
  2264.     }
  2265. }
  2266.  
  2267. cSprite *Get_Level_Object( const CEGUI::String &xml_element, CEGUI::XMLAttributes &attributes, float engine_version /* = level_engine_version */ )
  2268. {
  2269.     // element could change
  2270.     CEGUI::String element = xml_element;
  2271.  
  2272.     if( element == "sprite" )
  2273.     {
  2274.         // if V.1.5 and lower : change pipe connection image paths
  2275.         if( engine_version < 2.8f )
  2276.         {
  2277.             Relocate_Image( attributes, "blocks/pipe/connection_left_down.png", "blocks/pipe/connection/plastic_1/orange/right_up.png" );
  2278.             Relocate_Image( attributes, "blocks/pipe/connection_left_up.png", "blocks/pipe/connection/plastic_1/orange/right_down.png" );
  2279.             Relocate_Image( attributes, "blocks/pipe/connection_right_down.png", "blocks/pipe/connection/plastic_1/orange/left_up.png" );
  2280.             Relocate_Image( attributes, "blocks/pipe/connection_right_up.png", "blocks/pipe/connection/plastic_1/orange/left_down.png" );
  2281.             Relocate_Image( attributes, "blocks/pipe/metal_connector.png", "blocks/pipe/connection/metal_1/grey/middle.png" );
  2282.         }
  2283.  
  2284.         // if V.1.4 and lower : change some image paths
  2285.         if( engine_version < 2.5f )
  2286.         {
  2287.             // change stone8 to metal stone 2 violet
  2288.             Relocate_Image( attributes, "game/box/stone8.png", "blocks/metal/stone_2_violet.png" );
  2289.             // move jungle_1 trees into a directory
  2290.             Relocate_Image( attributes, "ground/jungle_1/tree_type_1.png", "ground/jungle_1/tree/1.png" );
  2291.             Relocate_Image( attributes, "ground/jungle_1/tree_type_1_front.png", "ground/jungle_1/tree/1_front.png" );
  2292.             Relocate_Image( attributes, "ground/jungle_1/tree_type_2.png", "ground/jungle_1/tree/2.png" );
  2293.             // move yoshi_1 extra to jungle_2 hedge
  2294.             Relocate_Image( attributes, "ground/yoshi_1/extra_1_blue.png", "ground/jungle_2/hedge/1_blue.png" );
  2295.             Relocate_Image( attributes, "ground/yoshi_1/extra_1_green.png", "ground/jungle_2/hedge/1_green.png" );
  2296.             Relocate_Image( attributes, "ground/yoshi_1/extra_1_red.png", "ground/jungle_2/hedge/1_red.png" );
  2297.             Relocate_Image( attributes, "ground/yoshi_1/extra_1_yellow.png", "ground/jungle_2/hedge/1_yellow.png" );
  2298.             // move yoshi_1 rope to jungle_2
  2299.             Relocate_Image( attributes, "ground/yoshi_1/rope_1_leftright.png", "ground/jungle_2/rope_1_hor.png" );
  2300.         }
  2301.  
  2302.         cSprite *sprite = new cSprite( attributes );
  2303.  
  2304.         // if V.1.2 and lower : change pipe position
  2305.         if( engine_version < 2.2f && sprite->image )
  2306.         {
  2307.             if( sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/green/up.png" ) == 0 ||
  2308.                 sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/green/ver.png" ) == 0 || 
  2309.                 sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/green/down.png" ) == 0 || 
  2310.                 sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/blue/up.png" ) == 0 ||
  2311.                 sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/blue/ver.png" ) == 0 || 
  2312.                 sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/blue/down.png" ) == 0 ||
  2313.                 sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/yellow/up.png" ) == 0 ||
  2314.                 sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/yellow/ver.png" ) == 0 || 
  2315.                 sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/yellow/down.png" ) == 0 ||
  2316.                 sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/grey/up.png" ) == 0 ||
  2317.                 sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/grey/ver.png" ) == 0 || 
  2318.                 sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/grey/down.png" ) == 0 )
  2319.             {
  2320.                 sprite->Move( -6, 0, 1 );
  2321.                 sprite->startposx = sprite->posx;
  2322.             }
  2323.             else if( sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/green/right.png" ) == 0 ||
  2324.                 sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/green/hor.png" ) == 0 || 
  2325.                 sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/green/left.png" ) == 0 ||
  2326.                 sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/blue/right.png" ) == 0 ||
  2327.                 sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/blue/hor.png" ) == 0 || 
  2328.                 sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/blue/left.png" ) == 0 ||
  2329.                 sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/yellow/right.png" ) == 0 ||
  2330.                 sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/yellow/hor.png" ) == 0 || 
  2331.                 sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/yellow/left.png" ) == 0 ||
  2332.                 sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/grey/right.png" ) == 0 ||
  2333.                 sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/grey/hor.png" ) == 0 || 
  2334.                 sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "pipes/grey/left.png" ) == 0 )
  2335.             {
  2336.                 sprite->Move( 0, -6, 1 );
  2337.                 sprite->startposy = sprite->posy;
  2338.             }
  2339.         }
  2340.         // if V.1.2 and lower : change some hill positions
  2341.         if( engine_version < 2.3f && sprite->image )
  2342.         {
  2343.             if( sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "hills/green_1/head.png" ) == 0 ||
  2344.                 sprite->image->filename.compare( DATA_DIR "/" GAME_PIXMAPS_DIR "/" "hills/light_blue_1/head.png" ) == 0 )
  2345.             {
  2346.                 sprite->Move( 0, -6, 1 );
  2347.                 sprite->startposy = sprite->posy;
  2348.             }
  2349.         }
  2350.  
  2351.         return sprite;
  2352.     }
  2353.     else if( element == "enemystopper" )
  2354.     {
  2355.         return new cEnemyStopper( attributes );
  2356.     }
  2357.     else if( element == "levelexit" )
  2358.     {
  2359.         return new cLevel_Exit( attributes );
  2360.     }
  2361.     else if( element == "level_entry" )
  2362.     {
  2363.         return new cLevel_Entry( attributes );
  2364.     }
  2365.     else if( element == "box" )
  2366.     {
  2367.         CEGUI::String str_type = attributes.getValueAsString( "type" );
  2368.  
  2369.         if( str_type == "bonus" )
  2370.         {
  2371.             return new cBonusBox( attributes );
  2372.         }
  2373.         // gold is somewhere pre 0.99.5
  2374.         else if( str_type == "gold" )
  2375.         {
  2376.             // update old values
  2377.             attributes.add( "type", "bonus" );
  2378.             attributes.add( "animation", "Default" );
  2379.             attributes.add( "item", int_to_string( TYPE_GOLDPIECE ) );
  2380.             // renamed color to gold_color
  2381.             if( attributes.exists( "color" ) )
  2382.             {
  2383.                 attributes.add( "gold_color", attributes.getValue( "color" ) );
  2384.                 attributes.remove( "color" );
  2385.             }
  2386.  
  2387.             return new cBonusBox( attributes );
  2388.         }
  2389.         else if( str_type == "spin" )
  2390.         {
  2391.             return new cSpinBox( attributes );
  2392.         }
  2393.         else if( str_type == "text" )
  2394.         {
  2395.             return new cText_Box( attributes );
  2396.         }
  2397.         // pre 0.99.4
  2398.         else if ( str_type == "empty" )
  2399.         {
  2400.             // update old values
  2401.             attributes.add( "type", "bonus" );
  2402.             attributes.add( "item", "0" );
  2403.  
  2404.             return new cBonusBox( attributes );
  2405.         }
  2406.         // pre 0.99.4
  2407.         else if ( str_type == "invisible" )
  2408.         {
  2409.             // update old values
  2410.             attributes.add( "type", "bonus" );
  2411.             attributes.add( "item", "0" );
  2412.             attributes.add( "invisible", "1" );
  2413.  
  2414.             return new cBonusBox( attributes );
  2415.         }
  2416.         else
  2417.         {
  2418.             printf( "Warning : Unknown Level Box type : %s\n", str_type.c_str() );
  2419.         }
  2420.     }
  2421.     // powerup is pre 0.99.5
  2422.     else if( element == "item" || element == "powerup" )
  2423.     {
  2424.         CEGUI::String str_type = attributes.getValueAsString( "type" );
  2425.  
  2426.         if( str_type == "goldpiece" )
  2427.         {
  2428.             return new cGoldpiece( attributes );
  2429.         }
  2430.         else if( str_type == "mushroom" )
  2431.         {
  2432.             return new cMushroom( attributes );
  2433.         }
  2434.         else if( str_type == "moon" )
  2435.         {
  2436.             return new cMoon( attributes );
  2437.         }
  2438.         else
  2439.         {
  2440.             printf( "Warning : Unknown Level Item type : %s\n", str_type.c_str() );
  2441.         }
  2442.     }
  2443.     else if( element == "moving_platform" )
  2444.     {
  2445.         return new cMoving_Platform( attributes );
  2446.     }
  2447.     // pre 1.5
  2448.     else if( element == "falling_platform" )
  2449.     {
  2450.         // no moving
  2451.         attributes.add( "speed", "0" );
  2452.         // renamed time_fall to touch_time and change to the new value
  2453.         if( attributes.exists( "time_fall" ) )
  2454.         {
  2455.             attributes.add( "touch_time", CEGUI::PropertyHelper::floatToString( attributes.getValueAsFloat( "time_fall" ) * speedfactor_fps ) );
  2456.             attributes.remove( "time_fall" );
  2457.         }
  2458.         else
  2459.         {
  2460.             attributes.add( "touch_time", "48" );
  2461.         }
  2462.         // enable falling
  2463.         attributes.add( "shake_time", "12" );
  2464.  
  2465.         return new cMoving_Platform( attributes );
  2466.     }
  2467.     else if( element == "enemy" )
  2468.     {
  2469.         CEGUI::String str_type = attributes.getValueAsString( "type" );
  2470.  
  2471.         // if V.1.5 and lower
  2472.         if( engine_version < 2.6f )
  2473.         {
  2474.             // change gumba to furball
  2475.             if( str_type == "gumba" )
  2476.             {
  2477.                 // change type
  2478.                 str_type = "furball";
  2479.                 attributes.add( "type", "furball" );
  2480.                 // fix color : red was used in pre 1.0 but later was blue
  2481.                 if( attributes.exists( "color" ) && attributes.getValueAsString( "color" ) == "red" )
  2482.                 {
  2483.                     attributes.add( "color", "blue" );
  2484.                 }
  2485.             }
  2486.             // change rex to krush
  2487.             else if( str_type == "rex" )
  2488.             {
  2489.                 // change type
  2490.                 str_type = "krush";
  2491.                 attributes.add( "type", "krush" );
  2492.             }
  2493.         }
  2494.  
  2495.         if( str_type == "eato" )
  2496.         {
  2497.             return new cEato( attributes );
  2498.         }
  2499.         else if( str_type == "furball" )
  2500.         {
  2501.             return new cFurball( attributes );
  2502.         }
  2503.         else if( str_type == "turtle" )
  2504.         {
  2505.             return new cTurtle( attributes );
  2506.         }
  2507.         else if( str_type == "turtleboss" )
  2508.         {
  2509.             // if V.1.5 and lower : max_downgrade_time changed to shell_time
  2510.             if( engine_version < 2.7f )
  2511.             {
  2512.                 if( attributes.exists( "max_downgrade_time" ) )
  2513.                 {
  2514.                     attributes.add( "shell_time", attributes.getValueAsString( "max_downgrade_time" ) );
  2515.                     attributes.remove( "max_downgrade_time" );
  2516.                 }
  2517.             }
  2518.  
  2519.             return new cTurtleBoss( attributes );
  2520.         }
  2521.         else if( str_type == "jpiranha" )
  2522.         {
  2523.             return new cjPiranha( attributes );
  2524.         }
  2525.         else if( str_type == "thromp" )
  2526.         {
  2527.             cThromp *thromp = new cThromp( attributes );
  2528.  
  2529.             // if V.1.4 and lower : fix thromp distance was smaller
  2530.             if( engine_version < 2.5f )
  2531.             {
  2532.                 thromp->Set_Max_Distance( thromp->max_distance + 36 );
  2533.             }
  2534.  
  2535.             return thromp;
  2536.         }
  2537.         else if( str_type == "rokko" )
  2538.         {
  2539.             return new cRokko( attributes );
  2540.         }
  2541.         else if( str_type == "krush" )
  2542.         {
  2543.             return new cKrush( attributes );
  2544.         }
  2545.         else if( str_type == "gee" )
  2546.         {
  2547.             return new cGee( attributes );
  2548.         }
  2549.         else if( str_type == "spika" )
  2550.         {
  2551.             return new cSpika( attributes );
  2552.         }
  2553.         else if( str_type == "static" )
  2554.         {
  2555.             return new cStaticEnemy( attributes );
  2556.         }
  2557.         else
  2558.         {
  2559.             printf( "Warning : Unknown Level Enemy type : %s\n", str_type.c_str() );
  2560.         }
  2561.     }
  2562.     else if( element == "sound" )
  2563.     {
  2564.         return new cRandom_Sound( attributes );
  2565.     }
  2566.     else if( element == "particle_emitter" )
  2567.     {
  2568.         cParticle_Emitter *particle_emitter = new cParticle_Emitter( attributes );
  2569.         // set to not spawned
  2570.         particle_emitter->spawned = 0;
  2571.         // init animation
  2572.         particle_emitter->Init_Anim();
  2573.  
  2574.         return particle_emitter;
  2575.     }
  2576.  
  2577.     return NULL;
  2578. }
  2579.  
  2580. /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
  2581.  
  2582. cLevel *pActive_Level = NULL;
  2583.