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

  1. /***************************************************************************
  2.  * animation.cpp  -  Animation and Particle classes
  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 "../video/animation.h"
  17. #include "../core/framerate.h"
  18. #include "../core/game_core.h"
  19. #include "../video/gl_surface.h"
  20. #include "../video/renderer.h"
  21. #include "../core/math/utilities.h"
  22. #include "../core/i18n.h"
  23.  
  24. /* *** *** *** *** *** *** *** Base Animation class *** *** *** *** *** *** *** *** *** *** */
  25.  
  26. cAnimation :: cAnimation( float x /* = 0 */, float y /* = 0 */ )
  27. : cImageObjectSprite( x, y )
  28. {
  29.     sprite_array = ARRAY_ANIM;
  30.     type = TYPE_ACTIVESPRITE;
  31.     massivetype = MASS_PASSIVE;
  32.     spawned = 1;
  33.  
  34.     posz = 0.07000f;
  35.     posz_rand = 0;
  36.     time_to_live = 0;
  37.     time_to_live_rand = 0;
  38.  
  39.     fading_speed = 1;
  40.     animtype = ANIM_UNDEFINED;
  41. }
  42.  
  43. cAnimation :: ~cAnimation( void )
  44. {
  45.     //
  46. }
  47.  
  48. void cAnimation :: Init_Anim( void )
  49. {
  50.     // virtual
  51. }
  52.  
  53. void cAnimation :: Update( void )
  54. {
  55.     // virtual
  56. }
  57.  
  58. void cAnimation :: Draw( cSurfaceRequest *request /* = NULL */ )
  59. {
  60. }
  61.  
  62.  
  63. void cAnimation :: Set_Time_to_Live( float time, float time_rand /* = 0 */ )
  64. {
  65.     time_to_live = time;
  66.     time_to_live_rand = time_rand;
  67. }
  68.  
  69. void cAnimation :: Set_Fading_Speed( float speed )
  70. {
  71.     fading_speed = speed;
  72.  
  73.     if( fading_speed <= 0 )
  74.     {
  75.         fading_speed = 0.1f;
  76.     }
  77. }
  78.  
  79. void cAnimation :: Set_Pos_Z( float pos, float pos_rand /* = 0 */ )
  80. {
  81.     posz = pos;
  82.     posz_rand = pos_rand;
  83. }
  84.  
  85. /* *** *** *** *** *** *** *** cAnimation_Goldpiece *** *** *** *** *** *** *** *** *** *** */
  86.  
  87. cAnimation_Goldpiece :: cAnimation_Goldpiece( float posx, float posy, float height /* = 40 */, float width /* = 20 */ )
  88. : cAnimation( posx, posy )
  89. {
  90.     animtype = BLINKING_POINTS;
  91.  
  92.     images.push_back( pVideo->Get_Surface( "animation/light_1/1.png" ) );
  93.     images.push_back( pVideo->Get_Surface( "animation/light_1/2.png" ) );
  94.     images.push_back( pVideo->Get_Surface( "animation/light_1/3.png" ) );
  95.  
  96.     for( unsigned int i = 0; i < 4; i++ )
  97.     {
  98.         cSprite *obj = new cSprite( NULL, Get_Random_Float( 0, width ), Get_Random_Float( 0, height ) );
  99.         objects.push_back( obj );
  100.     }
  101. }
  102.  
  103. cAnimation_Goldpiece :: ~cAnimation_Goldpiece( void )
  104. {
  105.     // clear
  106.     for( BlinkPointList::iterator itr = objects.begin(), itr_end = objects.end(); itr != itr_end; ++itr )
  107.     {
  108.         delete *itr;
  109.     }
  110.  
  111.     objects.clear();
  112. }
  113.  
  114. void cAnimation_Goldpiece :: Update( void )
  115. {
  116.     time_to_live += pFramerate->speedfactor * fading_speed;
  117.  
  118.     // update the fixed points
  119.     for( unsigned int i = 0; i < objects.size(); i++ )
  120.     {
  121.         switch( i ) 
  122.         {
  123.         case 0:
  124.         {
  125.             if( time_to_live < 3 )
  126.             {
  127.                 Set_Image( 0 );
  128.             }
  129.             else if( time_to_live < 6 )
  130.             {
  131.                 Set_Image( 0 );
  132.             }
  133.             else if( time_to_live < 9 )
  134.             {
  135.                 Set_Image( 1 );
  136.             }
  137.             else if( time_to_live < 12 )
  138.             {
  139.                 Set_Image( 0 );
  140.             }
  141.             break;
  142.         }
  143.         case 1:
  144.         {
  145.             if( time_to_live < 3 )
  146.             {
  147.                 Set_Image( 0 );
  148.             }
  149.             else if( time_to_live < 6 )
  150.             {
  151.                 Set_Image( 1 );
  152.             }
  153.             else if( time_to_live < 9 )
  154.             {
  155.                 Set_Image( 2 );
  156.             }
  157.             else if( time_to_live < 12 )
  158.             {
  159.                 Set_Image( 1 );
  160.             }
  161.             break;
  162.         }
  163.         case 2:
  164.         {
  165.             if( time_to_live < 3 )
  166.             {
  167.                 Set_Image( 1 );
  168.             }
  169.             else if( time_to_live < 6 )
  170.             {
  171.                 Set_Image( 2 );
  172.             }
  173.             else if( time_to_live < 9 )
  174.             {
  175.                 Set_Image( 0 );
  176.             }
  177.             else if( time_to_live < 12 )
  178.             {
  179.                 Set_Image( -1 );
  180.             }
  181.             break;            
  182.         }
  183.         case 3:
  184.         {
  185.             if( time_to_live < 3 )
  186.             {
  187.                 Set_Image( 0 );
  188.             }
  189.             else if( time_to_live < 6 )
  190.             {
  191.                 Set_Image( 1 );
  192.             }
  193.             else if( time_to_live < 9 )
  194.             {
  195.                 Set_Image( 0 );
  196.             }
  197.             else if( time_to_live < 12 )
  198.             {
  199.                 Set_Image( 0 );
  200.             }
  201.             break;
  202.         }
  203.         default:
  204.         {
  205.             break;
  206.         }
  207.         }
  208.  
  209.         objects[i]->Set_Scale( 1.1f - ( time_to_live / 12 ) );
  210.     }
  211. }
  212.  
  213. void cAnimation_Goldpiece :: Draw( cSurfaceRequest *request /* = NULL */ )
  214. {
  215.     if( !visible )
  216.     {
  217.         return;
  218.     }
  219.  
  220.     if( !image )
  221.     {
  222.         Set_Visible( 0 );
  223.         return;
  224.     }
  225.  
  226.     // draw the fixed points
  227.     for( BlinkPointList::iterator itr = objects.begin(), itr_end = objects.end(); itr != itr_end; ++itr )
  228.     {
  229.         cSprite *obj = (*itr);
  230.  
  231.         // create request
  232.         cSurfaceRequest *request = new cSurfaceRequest();
  233.         image->Blit( obj->posx - ( pActive_Camera->x - posx ), obj->posy - ( pActive_Camera->y - posy ), posz, request );
  234.  
  235.         // scale
  236.         request->scale_x = obj->scalex;
  237.         request->scale_y = obj->scaley;
  238.  
  239.         // color
  240.         request->color = color;
  241.  
  242.         // add request
  243.         pRenderer->Add( request );
  244.     }
  245.     
  246.     if( time_to_live > 11 || time_to_live < 0 )
  247.     {
  248.         Set_Visible( 0 );
  249.     }
  250. }
  251.  
  252. /* *** *** *** *** *** *** *** cAnimation_Fireball *** *** *** *** *** *** *** *** *** *** */
  253.  
  254. cAnimation_Fireball :: cAnimation_Fireball( float posx, float posy, unsigned int power /* = 5 */ )
  255. : cAnimation( posx, posy )
  256. {
  257.     animtype = FIRE_EXPLOSION;
  258.  
  259.     // create objects
  260.     for( unsigned int i = 0; i < power; i++ )
  261.     {
  262.         cAnimation_Fireball_Item *obj = new cAnimation_Fireball_Item();
  263.         objects.push_back( obj );
  264.     }
  265. }
  266.  
  267. cAnimation_Fireball :: ~cAnimation_Fireball( void )
  268. {
  269.     // clear
  270.     for( FireAnimList::iterator itr = objects.begin(), itr_end = objects.end(); itr != itr_end; ++itr )
  271.     {
  272.         delete *itr;
  273.     }
  274.  
  275.     objects.clear();
  276. }
  277.  
  278. void cAnimation_Fireball :: Init_Anim( void )
  279. {
  280.     for( FireAnimList::iterator itr = objects.begin(), itr_end = objects.end(); itr != itr_end; ++itr )
  281.     {
  282.         cAnimation_Fireball_Item *obj = (*itr);
  283.  
  284.         // images
  285.         obj->images.push_back( pVideo->Get_Surface( "animation/fire_1/4.png" ) );
  286.         obj->images.push_back( pVideo->Get_Surface( "animation/fire_1/3.png" ) );
  287.         obj->images.push_back( pVideo->Get_Surface( "animation/fire_1/2.png" ) );
  288.         obj->images.push_back( pVideo->Get_Surface( "animation/fire_1/1.png" ) );
  289.         obj->Set_Image( 0 );
  290.  
  291.         // velocity
  292.         obj->velx = Get_Random_Float( -2.5f, 5 );
  293.         obj->vely = Get_Random_Float( -2.5f, 5 );
  294.  
  295.         // Z position
  296.         obj->posz = posz;
  297.         if( posz_rand > 0 )
  298.         {
  299.             obj->posz += Get_Random_Float( 0, posz_rand );
  300.         }
  301.  
  302.         // lifetime
  303.         obj->counter = Get_Random_Float( 8, 13 );
  304.     }
  305. }
  306.  
  307. void cAnimation_Fireball :: Update( void )
  308. {
  309.     if( !visible )
  310.     {
  311.         return;
  312.     }
  313.  
  314.     time_to_live += pFramerate->speedfactor * fading_speed;
  315.  
  316.     // update objects
  317.     for( FireAnimList::iterator itr = objects.begin(), itr_end = objects.end(); itr != itr_end; ++itr )
  318.     {
  319.         cAnimation_Fireball_Item *obj = (*itr);
  320.  
  321.         if( obj->counter > 8 )
  322.         {
  323.             obj->Set_Image( 0 );
  324.         }
  325.         else if( obj->counter > 5 )
  326.         {
  327.             obj->Set_Image( 1 );
  328.         }
  329.         else if( obj->counter > 3 )
  330.         {
  331.             obj->Set_Image( 2 );
  332.         }
  333.         else
  334.         {
  335.             obj->Set_Image( 3 );
  336.         }
  337.  
  338.         obj->counter -= pFramerate->speedfactor * fading_speed;
  339.  
  340.         obj->Set_Scale( obj->counter / 10 );
  341.         obj->Move( obj->velx, obj->vely );
  342.     }
  343.  
  344.     if( time_to_live > 12 || time_to_live < 0 )
  345.     {
  346.         Set_Visible( 0 );
  347.     }
  348. }
  349.  
  350. void cAnimation_Fireball :: Draw( cSurfaceRequest *request /* = NULL */ )
  351. {
  352.     if( !visible )
  353.     {
  354.         return;
  355.     }
  356.  
  357.     // draw objects
  358.     for( FireAnimList::iterator itr = objects.begin(), itr_end = objects.end(); itr != itr_end; ++itr )
  359.     {
  360.         cAnimation_Fireball_Item *obj = (*itr);
  361.  
  362.         // create request
  363.         cSurfaceRequest *request = new cSurfaceRequest();
  364.         obj->image->Blit( obj->posx - ( pActive_Camera->x - posx ), obj->posy - ( pActive_Camera->y - posy ), obj->posz, request );
  365.  
  366.         // scale
  367.         request->scale_x = obj->scalex;
  368.         request->scale_y = obj->scaley;
  369.  
  370.         // color
  371.         request->color = color;
  372.  
  373.         // add request
  374.         pRenderer->Add( request );
  375.     }
  376. }
  377.  
  378. /* *** *** *** *** *** *** *** cParticle *** *** *** *** *** *** *** *** *** *** */
  379.  
  380. cParticle :: cParticle( void )
  381. : cMovingSprite()
  382. {
  383.     // scale centered
  384.     Set_Scale_Directions( 1, 1, 1, 1 );
  385.     time_to_live = 0;
  386.     const_rotx = 0;
  387.     const_roty = 0;
  388.     const_rotz = 0;
  389.     gravity_x = 0;
  390.     gravity_y = 0;
  391.  
  392.     fade_pos = 1;
  393. }
  394.  
  395. cParticle :: ~cParticle( void )
  396. {
  397.  
  398. }
  399.  
  400. void cParticle :: Update( void )
  401. {
  402.     // update fade modifier
  403.     fade_pos -= ( pFramerate->speedfactor * ( static_cast<float>(speedfactor_fps) * 0.001f ) ) / time_to_live;
  404.  
  405.     // finished fading
  406.     if( fade_pos <= 0 )
  407.     {
  408.         fade_pos = 0;
  409.         Set_Visible( 0 );
  410.         return;
  411.     }
  412.  
  413.     // move
  414.     Move( velx, vely );
  415.     // add gravity velocity
  416.     Add_Velocity( gravity_x, gravity_y );
  417.  
  418.     // constant rotation
  419.     if( const_rotx != 0 )
  420.     {
  421.         Add_Rotation_X( const_rotx * pFramerate->speedfactor );
  422.     }
  423.     if( const_roty != 0 )
  424.     {
  425.         Add_Rotation_Y( const_roty * pFramerate->speedfactor );
  426.     }
  427.     if( const_rotz != 0 )
  428.     {
  429.         Add_Rotation_Z( const_rotz * pFramerate->speedfactor );
  430.     }
  431. }
  432.  
  433. void cParticle :: Draw( cParticle_Emitter *origin )
  434. {
  435.     if( !image )
  436.     {
  437.         return;
  438.     }
  439.  
  440.     // create request
  441.     cSurfaceRequest *request = new cSurfaceRequest();
  442.  
  443.     image->Blit( posx - pActive_Camera->x, posy - pActive_Camera->y, posz, request );
  444.  
  445.     // blending
  446.     if( origin->blending == BLEND_ADD )
  447.     {
  448.         request->blend_sfactor = GL_SRC_ALPHA;
  449.         request->blend_dfactor = GL_ONE;
  450.     }
  451.     else if( origin->blending == BLEND_DRIVE )
  452.     {
  453.         request->blend_sfactor = GL_SRC_COLOR;
  454.         request->blend_dfactor = GL_DST_ALPHA;
  455.     }
  456.  
  457.     // rotation
  458.     request->rotx += rotx;
  459.     request->roty += roty;
  460.     request->rotz += rotz;
  461.  
  462.     // scale
  463.     request->scale_x = scalex;
  464.     request->scale_y = scaley;
  465.  
  466.     // size fading
  467.     if( origin->fade_size )
  468.     {
  469.         request->scale_x *= fade_pos;
  470.         request->scale_y *= fade_pos;
  471.     }
  472.  
  473.     // color
  474.     request->color = color;
  475.  
  476.     // color fading
  477.     if( origin->fade_color )
  478.     {
  479.         request->color.red = static_cast<Uint8>(request->color.red * fade_pos);
  480.         request->color.green = static_cast<Uint8>(request->color.green * fade_pos);
  481.         request->color.blue = static_cast<Uint8>(request->color.blue * fade_pos);
  482.     }
  483.     // alpha fading
  484.     if( origin->fade_alpha )
  485.     {
  486.         request->color.alpha = static_cast<Uint8>(request->color.alpha * fade_pos);
  487.     }
  488.  
  489.     // add request
  490.     pRenderer->Add( request );
  491. }
  492.  
  493. void cParticle :: Set_Gravity( float x, float y)
  494. {
  495.     gravity_x = x;
  496.     gravity_y = y;
  497. }
  498.  
  499. /* *** *** *** *** *** *** *** cParticle_Emitter *** *** *** *** *** *** *** *** *** *** */
  500.  
  501. cParticle_Emitter :: cParticle_Emitter( void )
  502. : cAnimation()
  503. {
  504.     Init();
  505. }
  506.  
  507. cParticle_Emitter :: cParticle_Emitter( CEGUI::XMLAttributes &attributes )
  508. : cAnimation()
  509. {
  510.     Init();
  511.     Create_from_Stream( attributes );
  512. }
  513.  
  514. cParticle_Emitter :: ~cParticle_Emitter( void )
  515. {
  516.     Clear();
  517. }
  518.  
  519. void cParticle_Emitter :: Create_from_Stream( CEGUI::XMLAttributes &attributes )
  520. {
  521.     // filename
  522.     Set_Filename( attributes.getValueAsString( "file" ).c_str() );
  523.     // position z
  524.     Set_Pos_Z( attributes.getValueAsFloat( "pos_z", posz ), attributes.getValueAsFloat( "pos_z_rand", posz_rand ) );
  525.     // emitter rect
  526.     Set_Emitter_Rect( static_cast<float>(attributes.getValueAsInteger( "pos_x", static_cast<int>(posx) )), static_cast<float>(attributes.getValueAsInteger( "pos_y", static_cast<int>(posy) )), static_cast<float>(attributes.getValueAsInteger( "size_x", static_cast<int>(start_rect.w) )), static_cast<float>(attributes.getValueAsInteger( "size_y", static_cast<int>(start_rect.h) )) );
  527.     // emitter time to live
  528.     Set_Emitter_Time_to_Live( attributes.getValueAsFloat( "emitter_time_to_live", emitter_time_to_live ) );
  529.     // emitter interval
  530.     Set_Emitter_Iteration_Interval( attributes.getValueAsFloat( "emitter_interval", emitter_iteration_interval ) );
  531.     // quota/count
  532.     Set_Quota( attributes.getValueAsInteger( "quota", emitter_quota ) );
  533.     // time for particle to live
  534.     Set_Time_to_Live( attributes.getValueAsFloat( "time_to_live", time_to_live ), attributes.getValueAsFloat( "time_to_live_rand", time_to_live_rand ) );
  535.     // velocity
  536.     Set_Speed( attributes.getValueAsFloat( "vel", vel ), attributes.getValueAsFloat( "vel_rand", vel_rand ) );
  537.     // start rotation
  538.     Set_Rotation( attributes.getValueAsFloat( "rot_x", start_rotx ), attributes.getValueAsFloat( "rot_y", start_roty ), attributes.getValueAsFloat( "rot_z", start_rotz ), 1 );
  539.     Set_Start_Rot_Z_Uses_Direction( attributes.getValueAsBool( "start_rot_z_uses_direction", start_rot_z_uses_direction ) );
  540.     // constant rotation x
  541.     Set_Const_Rotation_X( attributes.getValueAsFloat( "const_rot_x", const_rotx ), attributes.getValueAsFloat( "const_rot_x_rand", const_rotx_rand ) );
  542.     // constant rotation y
  543.     Set_Const_Rotation_Y( attributes.getValueAsFloat( "const_rot_y", const_roty ), attributes.getValueAsFloat( "const_rot_y_rand", const_roty_rand ) );
  544.     // constant rotation z
  545.     Set_Const_Rotation_Z( attributes.getValueAsFloat( "const_rot_z", const_rotz ), attributes.getValueAsFloat( "const_rot_z_rand", const_rotz_rand ) );
  546.     // angle
  547.     Set_Direction_Range( attributes.getValueAsFloat( "angle_start", angle_start ), attributes.getValueAsFloat( "angle_range", angle_range ) );
  548.     // scale
  549.     Set_Scale( attributes.getValueAsFloat( "size_scale", size_scale ), attributes.getValueAsFloat( "size_scale_rand", size_scale_rand ) );
  550.     // horizontal gravity
  551.     Set_Horizontal_Gravity( attributes.getValueAsFloat( "gravity_x", gravity_x ), attributes.getValueAsFloat( "gravity_x_rand", gravity_x_rand )  );
  552.     // vertical gravity
  553.     Set_Vertical_Gravity( attributes.getValueAsFloat( "gravity_y", gravity_y ), attributes.getValueAsFloat( "gravity_y_rand", gravity_y_rand ) );
  554. }
  555.  
  556. void cParticle_Emitter :: Save_to_Stream( ofstream &file )
  557. {
  558.     file << "\t<particle_emitter>" << std::endl;
  559.  
  560.     // filename
  561.     file << "\t\t<Property name=\"file\" value=\"" << filename.c_str() << "\" />" << std::endl;
  562.     // position z
  563.     file << "\t\t<Property name=\"pos_z\" value=\"" << posz << "\" />" << std::endl;
  564.     file << "\t\t<Property name=\"pos_z_rand\" value=\"" << posz_rand << "\" />" << std::endl;
  565.     // emitter rect
  566.     file << "\t\t<Property name=\"pos_x\" value=\"" << static_cast<int>(startposx) << "\" />" << std::endl;
  567.     file << "\t\t<Property name=\"pos_y\" value=\"" << static_cast<int>(startposy) << "\" />" << std::endl;
  568.     file << "\t\t<Property name=\"size_x\" value=\"" << static_cast<int>(start_rect.w) << "\" />" << std::endl;
  569.     file << "\t\t<Property name=\"size_y\" value=\"" << static_cast<int>(start_rect.h) << "\" />" << std::endl;
  570.     // emitter time to live
  571.     file << "\t\t<Property name=\"emitter_time_to_live\" value=\"" << emitter_time_to_live << "\" />" << std::endl;
  572.     // emitter interval
  573.     file << "\t\t<Property name=\"emitter_interval\" value=\"" << emitter_iteration_interval << "\" />" << std::endl;
  574.     // quota/count
  575.     file << "\t\t<Property name=\"quota\" value=\"" << emitter_quota << "\" />" << std::endl;
  576.     // time to live
  577.     file << "\t\t<Property name=\"time_to_live\" value=\"" << time_to_live << "\" />" << std::endl;
  578.     file << "\t\t<Property name=\"time_to_live_rand\" value=\"" << time_to_live_rand << "\" />" << std::endl;
  579.     // velocity
  580.     file << "\t\t<Property name=\"vel\" value=\"" << vel << "\" />" << std::endl;
  581.     file << "\t\t<Property name=\"vel_rand\" value=\"" << vel_rand << "\" />" << std::endl;
  582.     // start rotation
  583.     file << "\t\t<Property name=\"rot_x\" value=\"" << start_rotx << "\" />" << std::endl;
  584.     file << "\t\t<Property name=\"rot_y\" value=\"" << start_roty << "\" />" << std::endl;
  585.     file << "\t\t<Property name=\"rot_z\" value=\"" << start_rotz << "\" />" << std::endl;
  586.     file << "\t\t<Property name=\"start_rot_z_uses_direction\" value=\"" << start_rot_z_uses_direction << "\" />" << std::endl;
  587.     // constant rotation x
  588.     file << "\t\t<Property name=\"const_rot_x\" value=\"" << const_rotx << "\" />" << std::endl;
  589.     file << "\t\t<Property name=\"const_rot_x_rand\" value=\"" << const_rotx_rand << "\" />" << std::endl;
  590.     // constant rotation y
  591.     file << "\t\t<Property name=\"const_rot_y\" value=\"" << const_roty << "\" />" << std::endl;
  592.     file << "\t\t<Property name=\"const_rot_y_rand\" value=\"" << const_roty_rand << "\" />" << std::endl;
  593.     // constant rotation z
  594.     file << "\t\t<Property name=\"const_rot_z\" value=\"" << const_rotz << "\" />" << std::endl;
  595.     file << "\t\t<Property name=\"const_rot_z_rand\" value=\"" << const_rotz_rand << "\" />" << std::endl;
  596.     // angle
  597.     file << "\t\t<Property name=\"angle_start\" value=\"" << angle_start << "\" />" << std::endl;
  598.     file << "\t\t<Property name=\"angle_range\" value=\"" << angle_range << "\" />" << std::endl;
  599.     // scale
  600.     file << "\t\t<Property name=\"size_scale\" value=\"" << size_scale << "\" />" << std::endl;
  601.     file << "\t\t<Property name=\"size_scale_rand\" value=\"" << size_scale_rand << "\" />" << std::endl;
  602.     // horizontal gravity
  603.     file << "\t\t<Property name=\"gravity_x\" value=\"" << gravity_x << "\" />" << std::endl;
  604.     file << "\t\t<Property name=\"gravity_x_rand\" value=\"" << gravity_x_rand << "\" />" << std::endl;
  605.     // vertical gravity
  606.     file << "\t\t<Property name=\"gravity_y\" value=\"" << gravity_y << "\" />" << std::endl;
  607.     file << "\t\t<Property name=\"gravity_y_rand\" value=\"" << gravity_y_rand << "\" />" << std::endl;
  608.  
  609.     file << "\t</particle_emitter>" << std::endl;
  610. }
  611.  
  612. void cParticle_Emitter :: Init( void )
  613. {
  614.     animtype = PARTICLE_EXPLOSION;
  615.     editor_posz = 0.111f;
  616.     sprite_array = ARRAY_ANIM;
  617.     type = TYPE_ANIMATION;
  618.     name = "Particle Emitter";
  619.  
  620.     rect.w = 0;
  621.     rect.h = 0;
  622.     col_rect.w = rect.w;
  623.     col_rect.h = rect.h;
  624.     start_rect.w = rect.w;
  625.     start_rect.h = rect.h;
  626.  
  627.     // 0 = 1 emit
  628.     emitter_time_to_live = 0;
  629.     emitter_iteration_interval = 0.2f;
  630.     emitter_quota = 1;
  631.  
  632.     // velocity
  633.     vel = 2;
  634.     vel_rand = 2;
  635.     // rotation
  636.     start_rot_z_uses_direction = 0;
  637.     const_rotx = 0;
  638.     const_roty = 0;
  639.     const_rotz = 0;
  640.     const_rotx_rand = 0;
  641.     const_roty_rand = 0;
  642.     const_rotz_rand = 0;
  643.     // angle
  644.     angle_start = 0;
  645.     angle_range = 360;
  646.     // scale
  647.     size_scale = 1;
  648.     size_scale_rand = 0;
  649.     // gravity
  650.     gravity_x = 0;
  651.     gravity_x_rand = 0;
  652.     gravity_y = 0;
  653.     gravity_y_rand = 0;
  654.  
  655.     // color
  656.     color_rand = Color( static_cast<Uint8>(0), 0, 0, 0 );
  657.     // default 1 second
  658.     time_to_live = 1;
  659.     // default fading is alpha
  660.     fade_size = 0;
  661.     fade_alpha = 1;
  662.     fade_color = 0;
  663.  
  664.     blending = BLEND_NONE;
  665.  
  666.     // animation data
  667.     emit_counter = 0;
  668.     emitter_living_time = 0;
  669. }
  670.  
  671. cParticle_Emitter *cParticle_Emitter :: Copy( void )
  672. {
  673.     cParticle_Emitter *particle_animation = new cParticle_Emitter();
  674.     particle_animation->Set_Pos( startposx, startposy, 1 );
  675.     particle_animation->Set_Pos_Z( posz, posz_rand );
  676.     particle_animation->Set_Filename( filename.c_str() );
  677.     particle_animation->Set_Emitter_Rect( rect );
  678.     particle_animation->Set_Emitter_Time_to_Live( emitter_time_to_live );
  679.     particle_animation->Set_Emitter_Iteration_Interval( emitter_iteration_interval );
  680.     particle_animation->Set_Quota( emitter_quota );
  681.     particle_animation->Set_Time_to_Live( time_to_live, time_to_live_rand );
  682.     particle_animation->Set_Speed( vel, vel_rand );
  683.     particle_animation->Set_Rotation( start_rotx, start_roty, start_rotz, 1 );
  684.     particle_animation->Set_Start_Rot_Z_Uses_Direction( start_rot_z_uses_direction );
  685.     particle_animation->Set_Const_Rotation_X( const_rotx, const_rotx_rand );
  686.     particle_animation->Set_Const_Rotation_Y( const_roty, const_roty_rand );
  687.     particle_animation->Set_Const_Rotation_Z( const_rotz, const_rotz_rand );
  688.     particle_animation->Set_Direction_Range( angle_start, angle_range );
  689.     particle_animation->Set_Scale( size_scale, size_scale_rand );
  690.     particle_animation->Set_Color( color, color_rand );
  691.     particle_animation->Set_Horizontal_Gravity( gravity_x, gravity_x_rand );
  692.     particle_animation->Set_Vertical_Gravity( gravity_y, gravity_y_rand );
  693.     particle_animation->spawned = spawned;
  694.  
  695.     return particle_animation;
  696. }
  697.  
  698. void cParticle_Emitter :: Init_Anim( void )
  699. {
  700.     Emit();
  701. }
  702.  
  703. void cParticle_Emitter :: Emit( void )
  704. {
  705.     if( !image )
  706.     {
  707.         printf( "Warning : cParticle_Emitter can not emit with no image set\n" );
  708.         return;
  709.     }
  710.  
  711.     for( unsigned int i = 0; i < emitter_quota; i++ )
  712.     {
  713.         cParticle *particle = new cParticle();
  714.  
  715.         // X Position
  716.         float x = posx;
  717.         if( rect.w > 0 )
  718.         {
  719.             x += Get_Random_Float( 0, rect.w );
  720.         }
  721.         // Y Position
  722.         float y = posy;
  723.         if( rect.h > 0 )
  724.         {
  725.             y += Get_Random_Float( 0, rect.h );
  726.         }
  727.         // Set Position
  728.         particle->Set_Pos( x, y, 1 );
  729.  
  730.         // Image
  731.         particle->Set_Image( image, 1, 0 );
  732.  
  733.         // Z position
  734.         particle->posz = posz;
  735.         if( posz_rand > 0 )
  736.         {
  737.             particle->posz += Get_Random_Float( 0, posz_rand );
  738.         }
  739.  
  740.         // angle range
  741.         float dir_angle = angle_start;
  742.         // start angle
  743.         if( angle_range > 0 )
  744.         {
  745.             dir_angle += Get_Random_Float( 0, angle_range );
  746.         }
  747.  
  748.         // Velocity
  749.         float speed = vel;
  750.         if( vel_rand > 0 )
  751.         {
  752.             speed += Get_Random_Float( 0, vel_rand );
  753.         }
  754.         // set Velocity
  755.         particle->Set_Direction( dir_angle, speed, 1 );
  756.  
  757.         // Start rotation
  758.         particle->rotx = start_rotx;
  759.         particle->roty = start_roty;
  760.         particle->rotz = start_rotz;
  761.  
  762.         // rotation z uses start direction
  763.         if( start_rot_z_uses_direction )
  764.         {
  765.             particle->rotz += dir_angle;
  766.         }
  767.  
  768.         // Constant rotation
  769.         particle->const_rotx = const_rotx;
  770.         particle->const_roty = const_roty;
  771.         particle->const_rotz = const_rotz;
  772.         if( const_rotx_rand > 0 )
  773.         {
  774.             particle->const_rotx += Get_Random_Float( 0, const_rotx_rand );
  775.         }
  776.         if( const_roty_rand > 0 )
  777.         {
  778.             particle->const_roty += Get_Random_Float( 0, const_roty_rand );
  779.         }
  780.         if( const_rotz_rand > 0 )
  781.         {
  782.             particle->const_rotz += Get_Random_Float( 0, const_rotz_rand );
  783.         }
  784.  
  785.         // Scale
  786.         particle->Set_Scale( size_scale );
  787.         if( size_scale_rand > 0 )
  788.         {
  789.             particle->Add_Scale( Get_Random_Float( 0, size_scale_rand ) );
  790.         }
  791.         // Gravity
  792.         float grav_x = gravity_x;
  793.         if( gravity_x_rand > 0 )
  794.         {
  795.             grav_x += Get_Random_Float( 0, gravity_x_rand );
  796.         }
  797.         float grav_y = gravity_y;
  798.         if( gravity_y_rand > 0 )
  799.         {
  800.             grav_y += Get_Random_Float( 0, gravity_y_rand );
  801.         }
  802.         // set Gravity
  803.         particle->Set_Gravity( grav_x, grav_y );
  804.  
  805.         // Color
  806.         particle->Set_Color( color );
  807.         if( color_rand.red > 0 )
  808.         {
  809.             particle->color.red += rand() % color_rand.red;
  810.         }
  811.         if( color_rand.green > 0 )
  812.         {
  813.             particle->color.green += rand() % color_rand.green;
  814.         }
  815.         if( color_rand.blue > 0 )
  816.         {
  817.             particle->color.blue += rand() % color_rand.blue;
  818.         }
  819.         if( color_rand.alpha > 0 )
  820.         {
  821.             particle->color.alpha += rand() % color_rand.alpha;
  822.         }
  823.  
  824.         // Time to life
  825.         particle->time_to_live = time_to_live;
  826.         if( time_to_live_rand > 0 )
  827.         {
  828.             particle->time_to_live += Get_Random_Float( 0, time_to_live_rand );
  829.         }
  830.  
  831.         objects.push_back( particle );
  832.     }
  833. }
  834.  
  835. void cParticle_Emitter :: Clear( void )
  836. {
  837.     // clear particles
  838.     for( ParticleList::iterator itr = objects.begin(), itr_end = objects.end(); itr != itr_end; ++itr )
  839.     {
  840.         delete *itr;
  841.     }
  842.  
  843.     objects.clear();
  844.  
  845.     // clear animation data
  846.     emit_counter = 0;
  847.     emitter_living_time = 0;
  848. }
  849.  
  850. void cParticle_Emitter :: Update( void )
  851. {
  852.     Update_Valid_Update();
  853.  
  854.     if( !valid_update )
  855.     {
  856.         return;
  857.     }
  858.     
  859.     emitter_living_time += pFramerate->speedfactor * ( static_cast<float>(speedfactor_fps) * 0.001f );
  860.  
  861.     // update objects
  862.     for( ParticleList::iterator itr = objects.begin(); itr != objects.end(); )
  863.     {
  864.         // get object pointer
  865.         cParticle *obj = (*itr);
  866.  
  867.         // update
  868.         obj->Update();
  869.  
  870.         // if finished
  871.         if( obj->fade_pos <= 0 )
  872.         {
  873.             itr = objects.erase( itr );
  874.             delete obj;
  875.         }
  876.         // increment
  877.         else
  878.         {
  879.             ++itr;
  880.         }
  881.     }
  882.  
  883.     // if able to emit or endless emitter
  884.     if( emitter_living_time < emitter_time_to_live || emitter_time_to_live == -1 )
  885.     {
  886.         // emit
  887.         while( emit_counter > emitter_iteration_interval )
  888.         {
  889.             Emit();
  890.             emit_counter -= emitter_iteration_interval;
  891.         }
  892.  
  893.         emit_counter += pFramerate->speedfactor * ( static_cast<float>(speedfactor_fps) * 0.001f );
  894.     }
  895.     // no particles are active
  896.     else if( !objects.size() )
  897.     {
  898.         Set_Visible( 0 );
  899.     }
  900. }
  901.  
  902. void cParticle_Emitter :: Draw( cSurfaceRequest *request /* = NULL */ )
  903. {
  904.     if( !valid_draw )
  905.     {
  906.         return;
  907.     }
  908.  
  909.     if( !editor_enabled )
  910.     {
  911.         for( ParticleList::iterator itr = objects.begin(), itr_end = objects.end(); itr != itr_end; ++itr )
  912.         {
  913.             (*itr)->Draw( this );
  914.         }
  915.     }
  916.     else
  917.     {
  918.         if( !spawned )
  919.         {
  920.             // draw color rect
  921.             GL_rect color_rect = GL_rect( col_rect.x - pActive_Camera->x, col_rect.y - pActive_Camera->y, col_rect.w, col_rect.h );
  922.  
  923.             // minimum visible rect size
  924.             if( color_rect.w < 5 )
  925.             {
  926.                 color_rect.w = 5;
  927.             }
  928.             if( color_rect.h < 5 )
  929.             {
  930.                 color_rect.h = 5;
  931.             }
  932.  
  933.             cRectRequest *rect_request = new cRectRequest();
  934.             pVideo->Draw_Rect( &color_rect, editor_posz, &darkgreen, rect_request );
  935.             rect_request->filled = 0;
  936.             pRenderer->Add( rect_request );
  937.         }
  938.     }
  939. }
  940.  
  941. bool cParticle_Emitter :: Is_Update_Valid( void )
  942. {
  943.     // if not visible
  944.     if( !visible )
  945.     {
  946.         return 0;
  947.     }
  948.  
  949.     // if not in player range and not visible on the screen
  950.     if( !is_Player_range() && !Is_Visible_on_Screen() )
  951.     {
  952.         return 0;
  953.     }
  954.  
  955.     return 1;
  956. }
  957.  
  958. bool cParticle_Emitter :: Is_Draw_Valid( void )
  959. {
  960.     // if not visible
  961.     if( !visible )
  962.     {
  963.         return 0;
  964.     }
  965.  
  966.     // if not in player range and not visible on the screen
  967.     if( !is_Player_range() && !Is_Visible_on_Screen() )
  968.     {
  969.         return 0;
  970.     }
  971.  
  972.     return 1;
  973. }
  974.  
  975. void cParticle_Emitter :: Set_Emitter_Rect( float x, float y, float w /* = 0 */, float h /* = 0 */ )
  976. {
  977.     // don't set x/y to 0 or the next Set_Pos call will overwrite the start position
  978.     if( x == 0 && y == 0 )
  979.     {
  980.         y = -1;
  981.     }
  982.  
  983.     Set_Pos( x, y, 1 );
  984.     rect.w = w;
  985.     rect.h = h;
  986.     col_rect.w = rect.w;
  987.     col_rect.h = rect.h;
  988.     start_rect.w = rect.w;
  989.     start_rect.h = rect.h;
  990.  
  991.     // invalid width
  992.     if( rect.w < 0 )
  993.     {
  994.         rect.w = 0;
  995.     }
  996.     // invalid height
  997.     if( rect.h < 0 )
  998.     {
  999.         rect.h = 0;
  1000.     }
  1001. }
  1002.  
  1003. void cParticle_Emitter :: Set_Emitter_Rect( GL_rect r )
  1004. {
  1005.     Set_Emitter_Rect( r.x, r.y, r.w, r.h );
  1006. }
  1007.  
  1008. void cParticle_Emitter :: Set_Emitter_Time_to_Live( float time )
  1009. {
  1010.     emitter_time_to_live = time;
  1011. }
  1012.  
  1013. void cParticle_Emitter :: Set_Emitter_Iteration_Interval( float time )
  1014. {
  1015.     if( time < 0.001f )
  1016.     {
  1017.         time = 0.001f;
  1018.     }
  1019.  
  1020.     emitter_iteration_interval = time;
  1021. }
  1022.  
  1023. void cParticle_Emitter :: Set_Quota( unsigned int size )
  1024. {
  1025.     if( size > 1000 )
  1026.     {
  1027.         size = 1000;
  1028.     }
  1029.  
  1030.     emitter_quota = size;
  1031. }
  1032.  
  1033. void cParticle_Emitter :: Set_Speed( float vel_base, float vel_random /* = 2 */ )
  1034. {
  1035.     vel = vel_base;
  1036.     vel_rand = vel_random;
  1037. }
  1038.  
  1039. void cParticle_Emitter :: Set_Start_Rot_Z_Uses_Direction( bool enable )
  1040. {
  1041.     start_rot_z_uses_direction = enable;
  1042. }
  1043.  
  1044. void cParticle_Emitter :: Set_Const_Rotation_X( float rot, float rot_random /* = 0 */ )
  1045. {
  1046.     const_rotx = rot;
  1047.     const_rotx_rand = rot_random;
  1048. }
  1049.  
  1050. void cParticle_Emitter :: Set_Const_Rotation_Y( float rot, float rot_random /* = 0 */ )
  1051. {
  1052.     const_roty = rot;
  1053.     const_roty_rand = rot_random;
  1054. }
  1055.  
  1056. void cParticle_Emitter :: Set_Const_Rotation_Z( float rot, float rot_random /* = 0 */ )
  1057. {
  1058.     const_rotz = rot;
  1059.     const_rotz_rand = rot_random;
  1060. }
  1061.  
  1062. void cParticle_Emitter :: Set_Direction_Range( float start, float range /* = 0 */ )
  1063. {
  1064.     angle_start = start;
  1065.     angle_range = range;
  1066. }
  1067.  
  1068. void cParticle_Emitter :: Set_Scale( float nscale, float scale_random /* = 0 */ )
  1069. {
  1070.     size_scale = nscale;
  1071.     size_scale_rand = scale_random;
  1072. }
  1073.  
  1074. void cParticle_Emitter :: Set_Horizontal_Gravity( float start, float random /* = 0 */ )
  1075. {
  1076.     gravity_x = start;
  1077.     gravity_x_rand = random;
  1078. }
  1079.  
  1080. void cParticle_Emitter :: Set_Vertical_Gravity( float start, float random /* = 0 */ )
  1081. {
  1082.     gravity_y = start;
  1083.     gravity_y_rand = random;
  1084. }
  1085.  
  1086. void cParticle_Emitter :: Set_Color( Color col, Color col_rand /* = Color( static_cast<Uint8>(0) ) */ )
  1087. {
  1088.     color = col;
  1089.     color_rand = col_rand;
  1090. }
  1091.  
  1092. void cParticle_Emitter :: Set_Fading_Size( bool enable )
  1093. {
  1094.     fade_size = enable;
  1095. }
  1096.  
  1097. void cParticle_Emitter :: Set_Fading_Alpha( bool enable )
  1098. {
  1099.     fade_alpha = enable;
  1100. }
  1101.  
  1102. void cParticle_Emitter :: Set_Fading_Color( bool enable )
  1103. {
  1104.     fade_color = enable;
  1105. }
  1106.  
  1107. void cParticle_Emitter :: Set_Blending( BlendingMode mode )
  1108. {
  1109.     blending = mode;
  1110. }
  1111.  
  1112. void cParticle_Emitter :: Set_Image( GL_Surface *img )
  1113. {
  1114.     if( !img )
  1115.     {
  1116.         return;
  1117.     }
  1118.  
  1119.     image = img;
  1120. }
  1121.  
  1122. void cParticle_Emitter :: Set_Filename( string str_filename )
  1123. {
  1124.     // remember the filename for saving
  1125.     filename = str_filename;
  1126.     Convert_Path_Separators( filename );
  1127.     // set new image
  1128.     Set_Image( pVideo->Get_Surface( filename, 0 ) );
  1129. }
  1130.  
  1131. void cParticle_Emitter :: Editor_Activate( void )
  1132. {
  1133.     CEGUI::WindowManager &wmgr = CEGUI::WindowManager::getSingleton();
  1134.  
  1135.     // position z base
  1136.     CEGUI::Editbox *editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_pos_z_base" ));
  1137.     Editor_Add( UTF8_("Position z"), UTF8_("Position z base"), editbox, 150 );
  1138.  
  1139.     editbox->setText( float_to_string( posz ) );
  1140.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Pos_Z_Base_Key, this ) );
  1141.  
  1142.     // position z rand
  1143.     editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_pos_z_rand" ));
  1144.     Editor_Add( UTF8_("Random"), UTF8_("Position z rand"), editbox, 150, 28, 0 );
  1145.  
  1146.     editbox->setText( float_to_string( posz_rand ) );
  1147.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Pos_Z_Rand_Key, this ) );
  1148.     
  1149.     // image filename
  1150.     editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_image_filename" ));
  1151.     Editor_Add( UTF8_("Filename"), UTF8_("Image filename"), editbox, 300 );
  1152.  
  1153.     editbox->setText( filename.c_str() );
  1154.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Filename_Key, this ) );
  1155.  
  1156.     // emitter width
  1157.     editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_width" ));
  1158.     Editor_Add( UTF8_("Emitter width"), UTF8_("Emitter width in which the particles spawn"), editbox, 150 );
  1159.  
  1160.     editbox->setText( float_to_string( rect.w ) );
  1161.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Emitter_Width_Key, this ) );
  1162.  
  1163.     // emitter height
  1164.     editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_height" ));
  1165.     Editor_Add( UTF8_("Height"), UTF8_("Emitter height in which the particles spawn"), editbox, 150, 28, 0 );
  1166.  
  1167.     editbox->setText( float_to_string( rect.h ) );
  1168.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Emitter_Height_Key, this ) );
  1169.  
  1170.     // emitter time to live
  1171.     editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_time_to_live" ));
  1172.     Editor_Add( UTF8_("Emitter TTL"), UTF8_("Emitter time to live. Set -1 for infinite."), editbox, 150 );
  1173.  
  1174.     editbox->setText( float_to_string( emitter_time_to_live ) );
  1175.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Emitter_Time_To_Live_Key, this ) );
  1176.  
  1177.     // emitter interval
  1178.     editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_interval" ));
  1179.     Editor_Add( UTF8_("Emitter interval"), UTF8_("Time between spawning particles based on the quota"), editbox, 150 );
  1180.  
  1181.     editbox->setText( float_to_string( emitter_iteration_interval ) );
  1182.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Emitter_Interval_Key, this ) );
  1183.  
  1184.     // quota
  1185.     editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_quota" ));
  1186.     Editor_Add( UTF8_("Quota"), UTF8_("The amount of particles to spawn for an interval"), editbox, 50 );
  1187.  
  1188.     editbox->setText( int_to_string( emitter_quota ) );
  1189.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Quota_Key, this ) );
  1190.  
  1191.     // time to live base
  1192.     editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_ttl_base" ));
  1193.     Editor_Add( UTF8_("TTL"), UTF8_("Time to live base"), editbox, 150 );
  1194.  
  1195.     editbox->setText( float_to_string( time_to_live ) );
  1196.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Ttl_Base_Key, this ) );
  1197.     
  1198.     // time to live rand
  1199.     editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_ttl_rand" ));
  1200.     Editor_Add( UTF8_("Random"), UTF8_("Time to live random"), editbox, 150, 28, 0 );
  1201.  
  1202.     editbox->setText( float_to_string( time_to_live_rand ) );
  1203.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Ttl_Rand_Key, this ) );
  1204.  
  1205.     // velocity base
  1206.     editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_vel_base" ));
  1207.     Editor_Add( UTF8_("Velocity"), UTF8_("Velocity base"), editbox, 150 );
  1208.  
  1209.     editbox->setText( float_to_string( vel ) );
  1210.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Velocity_Base_Key, this ) );
  1211.  
  1212.     // velocity rand
  1213.     editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_vel_rand" ));
  1214.     Editor_Add( UTF8_("Random"), UTF8_("Velocity random"), editbox, 150, 28, 0 );
  1215.  
  1216.     editbox->setText( float_to_string( vel_rand ) );
  1217.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Velocity_Rand_Key, this ) );
  1218.     
  1219.     // start rotation x base
  1220.     /*editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_rotation_x_base" ));
  1221.     Editor_Add( UTF8_("Rotation x"), UTF8_("Rotation x base"), editbox, 150 );
  1222.  
  1223.     editbox->setText( float_to_string( start_rotx ) );
  1224.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Rotation_X_Base_Key, this ) );
  1225.     */
  1226.     // start rotation y base
  1227.     /*editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_rotation_y_base" ));
  1228.     Editor_Add( UTF8_("Rotation y"), UTF8_("Rotation y base"), editbox, 150 );
  1229.  
  1230.     editbox->setText( float_to_string( start_roty ) );
  1231.     editbox->subscribeEvent( Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Rotation_Y_Base_Key, this ) );
  1232.     */
  1233.     // start rotation z base
  1234.     editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_rotation_z_base" ));
  1235.     Editor_Add( UTF8_("Rotation z"), UTF8_("Rotation z base"), editbox, 150 );
  1236.  
  1237.     editbox->setText( float_to_string( start_rotz ) );
  1238.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Rotation_Z_Base_Key, this ) );
  1239.     
  1240.     // start rotation z uses start direction
  1241.     CEGUI::Checkbox *checkbox = static_cast<CEGUI::Checkbox *>(wmgr.createWindow( "TaharezLook/Checkbox", "emitter_start_rot_z_uses_direction" ));
  1242.     Editor_Add( UTF8_("Add direction"), UTF8_("Start rotation z uses start direction"), checkbox, 50, 28, 0 );
  1243.  
  1244.     checkbox->setSelected( start_rot_z_uses_direction );
  1245.     checkbox->subscribeEvent( CEGUI::Checkbox::EventCheckStateChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Start_Rot_Z_Uses_Direction_Changed, this ) );
  1246.  
  1247.     // constant rotation x base
  1248.     /*editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_const_rotation_x_base" ));
  1249.     Editor_Add( UTF8_("Const. rotation x"), UTF8_("Constant rotation x base"), editbox, 150 );
  1250.  
  1251.     editbox->setText( float_to_string( const_rotx ) );
  1252.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Const_Rotation_X_Base_Key, this ) );
  1253.     */
  1254.     // constant rotation x rand
  1255.     /*editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_const_rotation_x_rand" ));
  1256.     Editor_Add( UTF8_("Random"), UTF8_("Constant rotation x random"), editbox, 150, 28, 0 );
  1257.  
  1258.     editbox->setText( float_to_string( const_rotx_rand ) );
  1259.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Const_Rotation_X_Rand_Key, this ) );
  1260.     */
  1261.     // constant rotation y base
  1262.     /*editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_const_rotation_y_base" ));
  1263.     Editor_Add( UTF8_("Const. rotation y"), UTF8_("Constant rotation y base"), editbox, 150 );
  1264.  
  1265.     editbox->setText( float_to_string( const_roty ) );
  1266.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Const_Rotation_Y_Base_Key, this ) );
  1267.     */
  1268.     // constant rotation y rand
  1269.     /*editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_const_rotation_y_rand" ));
  1270.     Editor_Add( UTF8_("Random"), UTF8_("Constant rotation y random"), editbox, 150, 28, 0 );
  1271.  
  1272.     editbox->setText( float_to_string( const_roty_rand ) );
  1273.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Const_Rotation_Y_Rand_Key, this ) );
  1274.     */
  1275.     // constant rotation z base
  1276.     editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_const_rotation_z_base" ));
  1277.     Editor_Add( UTF8_("Const. rotation z"), UTF8_("Constant rotation z base"), editbox, 150 );
  1278.  
  1279.     editbox->setText( float_to_string( const_rotz ) );
  1280.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Const_Rotation_Z_Base_Key, this ) );
  1281.     
  1282.     // constant rotation z rand
  1283.     editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_const_rotation_z_rand" ));
  1284.     Editor_Add( UTF8_("Random"), UTF8_("Constant rotation z random"), editbox, 150, 28, 0 );
  1285.  
  1286.     editbox->setText( float_to_string( const_rotz_rand ) );
  1287.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Const_Rotation_Z_Rand_Key, this ) );
  1288.  
  1289.     // direction base
  1290.     editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_direction_base" ));
  1291.     Editor_Add( UTF8_("Direction"), UTF8_("Direction start"), editbox, 150 );
  1292.  
  1293.     editbox->setText( float_to_string( angle_start ) );
  1294.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Direction_Base_Key, this ) );
  1295.  
  1296.     // direction rand
  1297.     editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_direction_rand" ));
  1298.     Editor_Add( UTF8_("Random"), UTF8_("Direction range"), editbox, 150, 28, 0 );
  1299.  
  1300.     editbox->setText( float_to_string( angle_range ) );
  1301.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Direction_Rand_Key, this ) );
  1302.  
  1303.     // scale base
  1304.     editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_scale_base" ));
  1305.     Editor_Add( UTF8_("Scale"), UTF8_("Scale base"), editbox, 150 );
  1306.  
  1307.     editbox->setText( float_to_string( size_scale ) );
  1308.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Scale_Base_Key, this ) );
  1309.  
  1310.     // scale rand
  1311.     editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_scale_rand" ));
  1312.     Editor_Add( UTF8_("Random"), UTF8_("Scale random"), editbox, 150, 28, 0 );
  1313.  
  1314.     editbox->setText( float_to_string( size_scale_rand ) );
  1315.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Scale_Rand_Key, this ) );
  1316.     
  1317.     // horizontal gravity base
  1318.     editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_hor_gravity_base" ));
  1319.     Editor_Add( UTF8_("Hor gravity"), UTF8_("Horizontal gravity base"), editbox, 150 );
  1320.  
  1321.     editbox->setText( float_to_string( gravity_x ) );
  1322.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Horizontal_Gravity_Base_Key, this ) );
  1323.  
  1324.     // horizontal gravity rand
  1325.     editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_hor_gravity_rand" ));
  1326.     Editor_Add( UTF8_("Random"), UTF8_("Horizontal gravity random"), editbox, 150, 28, 0 );
  1327.  
  1328.     editbox->setText( float_to_string( gravity_x_rand ) );
  1329.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Horizontal_Gravity_Rand_Key, this ) );
  1330.     
  1331.     // vertical gravity base
  1332.     editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_ver_gravity_base" ));
  1333.     Editor_Add( UTF8_("Ver gravity"), UTF8_("Vertical gravity base"), editbox, 150 );
  1334.  
  1335.     editbox->setText( float_to_string( gravity_y ) );
  1336.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Vertical_Gravity_Base_Key, this ) );
  1337.  
  1338.     // vertical gravity rand
  1339.     editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "emitter_ver_gravity_rand" ));
  1340.     Editor_Add( UTF8_("Random"), UTF8_("Vertical gravity random"), editbox, 150, 28, 0 );
  1341.  
  1342.     editbox->setText( float_to_string( gravity_y_rand ) );
  1343.     editbox->subscribeEvent( CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber( &cParticle_Emitter::Editor_Vertical_Gravity_Rand_Key, this ) );
  1344.  
  1345.     // init
  1346.     Editor_Init();
  1347. }
  1348.  
  1349. bool cParticle_Emitter :: Editor_Filename_Key( const CEGUI::EventArgs &event )
  1350. {
  1351.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1352.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1353.  
  1354.     Set_Filename( str_text );
  1355.  
  1356.     return 1;
  1357. }
  1358.  
  1359. bool cParticle_Emitter :: Editor_Pos_Z_Base_Key( const CEGUI::EventArgs &event )
  1360. {
  1361.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1362.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1363.  
  1364.     Set_Pos_Z( string_to_float( str_text ), posz_rand ); 
  1365.  
  1366.     return 1;
  1367. }
  1368.  
  1369. bool cParticle_Emitter :: Editor_Pos_Z_Rand_Key( const CEGUI::EventArgs &event )
  1370. {
  1371.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1372.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1373.  
  1374.     Set_Pos_Z( posz, string_to_float( str_text ) );
  1375.  
  1376.     return 1;
  1377. }
  1378.  
  1379. bool cParticle_Emitter :: Editor_Emitter_Width_Key( const CEGUI::EventArgs &event )
  1380. {
  1381.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1382.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1383.  
  1384.     Set_Emitter_Rect( posx, posy, string_to_float( str_text ), rect.h );
  1385.  
  1386.     return 1;
  1387. }
  1388.  
  1389. bool cParticle_Emitter :: Editor_Emitter_Height_Key( const CEGUI::EventArgs &event )
  1390. {
  1391.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1392.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1393.  
  1394.     Set_Emitter_Rect( posx, posy, rect.w, string_to_float( str_text ) );
  1395.  
  1396.     return 1;
  1397. }
  1398.  
  1399. bool cParticle_Emitter :: Editor_Emitter_Time_To_Live_Key( const CEGUI::EventArgs &event )
  1400. {
  1401.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1402.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1403.  
  1404.     Set_Emitter_Time_to_Live( string_to_float( str_text ) );
  1405.  
  1406.     return 1;
  1407. }
  1408.  
  1409. bool cParticle_Emitter :: Editor_Emitter_Interval_Key( const CEGUI::EventArgs &event )
  1410. {
  1411.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1412.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1413.  
  1414.     Set_Emitter_Iteration_Interval( string_to_float( str_text ) );
  1415.  
  1416.     return 1;
  1417. }
  1418.  
  1419. bool cParticle_Emitter :: Editor_Quota_Key( const CEGUI::EventArgs &event )
  1420. {
  1421.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1422.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1423.  
  1424.     Set_Quota( string_to_int( str_text ) );
  1425.     
  1426.     return 1;
  1427. }
  1428.  
  1429. bool cParticle_Emitter :: Editor_Ttl_Base_Key( const CEGUI::EventArgs &event )
  1430. {
  1431.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1432.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1433.  
  1434.     Set_Time_to_Live( string_to_float( str_text ), time_to_live_rand );
  1435.  
  1436.     return 1;
  1437. }
  1438.  
  1439. bool cParticle_Emitter :: Editor_Ttl_Rand_Key( const CEGUI::EventArgs &event )
  1440. {
  1441.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1442.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1443.  
  1444.     Set_Time_to_Live( time_to_live, string_to_float( str_text ) );
  1445.  
  1446.     return 1;
  1447. }
  1448.  
  1449. bool cParticle_Emitter :: Editor_Velocity_Base_Key( const CEGUI::EventArgs &event )
  1450. {
  1451.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1452.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1453.  
  1454.     Set_Speed( string_to_float( str_text ), vel_rand );
  1455.  
  1456.     return 1;
  1457. }
  1458.  
  1459. bool cParticle_Emitter :: Editor_Velocity_Rand_Key( const CEGUI::EventArgs &event )
  1460. {
  1461.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1462.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1463.  
  1464.     Set_Speed( vel, string_to_float( str_text ) );
  1465.  
  1466.     return 1;
  1467. }
  1468.  
  1469. bool cParticle_Emitter :: Editor_Rotation_X_Base_Key( const CEGUI::EventArgs &event )
  1470. {
  1471.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1472.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1473.  
  1474.     Set_Rotation_X( string_to_float( str_text ), 1 );
  1475.  
  1476.     return 1;
  1477. }
  1478.  
  1479. bool cParticle_Emitter :: Editor_Rotation_Y_Base_Key( const CEGUI::EventArgs &event )
  1480. {
  1481.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1482.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1483.  
  1484.     Set_Rotation_Y( string_to_float( str_text ), 1 );
  1485.  
  1486.     return 1;
  1487. }
  1488.  
  1489. bool cParticle_Emitter :: Editor_Start_Rot_Z_Uses_Direction_Changed( const CEGUI::EventArgs &event )
  1490. {
  1491.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1492.     bool enabled = static_cast<CEGUI::Checkbox *>( windowEventArgs.window )->isSelected();
  1493.  
  1494.     Set_Start_Rot_Z_Uses_Direction( enabled );
  1495.  
  1496.     return 1;
  1497. }
  1498.  
  1499. bool cParticle_Emitter :: Editor_Rotation_Z_Base_Key( const CEGUI::EventArgs &event )
  1500. {
  1501.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1502.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1503.  
  1504.     Set_Rotation_Z( string_to_float( str_text ), 1 );
  1505.  
  1506.     return 1;
  1507. }
  1508.  
  1509. bool cParticle_Emitter :: Editor_Const_Rotation_X_Base_Key( const CEGUI::EventArgs &event )
  1510. {
  1511.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1512.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1513.  
  1514.     Set_Const_Rotation_X( string_to_float( str_text ), const_rotz_rand );
  1515.  
  1516.     return 1;
  1517. }
  1518.  
  1519. bool cParticle_Emitter :: Editor_Const_Rotation_X_Rand_Key( const CEGUI::EventArgs &event )
  1520. {
  1521.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1522.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1523.  
  1524.     Set_Const_Rotation_X( const_rotz, string_to_float( str_text ) );
  1525.  
  1526.     return 1;
  1527. }
  1528.  
  1529. bool cParticle_Emitter :: Editor_Const_Rotation_Y_Base_Key( const CEGUI::EventArgs &event )
  1530. {
  1531.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1532.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1533.  
  1534.     Set_Const_Rotation_Y( string_to_float( str_text ), const_rotz_rand );
  1535.  
  1536.     return 1;
  1537. }
  1538.  
  1539. bool cParticle_Emitter :: Editor_Const_Rotation_Y_Rand_Key( const CEGUI::EventArgs &event )
  1540. {
  1541.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1542.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1543.  
  1544.     Set_Const_Rotation_Y( const_rotz, string_to_float( str_text ) );
  1545.  
  1546.     return 1;
  1547. }
  1548.  
  1549. bool cParticle_Emitter :: Editor_Const_Rotation_Z_Base_Key( const CEGUI::EventArgs &event )
  1550. {
  1551.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1552.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1553.  
  1554.     Set_Const_Rotation_Z( string_to_float( str_text ), const_rotz_rand );
  1555.  
  1556.     return 1;
  1557. }
  1558.  
  1559. bool cParticle_Emitter :: Editor_Const_Rotation_Z_Rand_Key( const CEGUI::EventArgs &event )
  1560. {
  1561.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1562.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1563.  
  1564.     Set_Const_Rotation_Z( const_rotz, string_to_float( str_text ) );
  1565.  
  1566.     return 1;
  1567. }
  1568.  
  1569. bool cParticle_Emitter :: Editor_Direction_Base_Key( const CEGUI::EventArgs &event )
  1570. {
  1571.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1572.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1573.  
  1574.     Set_Direction_Range( string_to_float( str_text ), angle_range );
  1575.  
  1576.     return 1;
  1577. }
  1578.  
  1579. bool cParticle_Emitter :: Editor_Direction_Rand_Key( const CEGUI::EventArgs &event )
  1580. {
  1581.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1582.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1583.  
  1584.     Set_Direction_Range( angle_start, string_to_float( str_text ) );
  1585.  
  1586.     return 1;
  1587. }
  1588.  
  1589. bool cParticle_Emitter :: Editor_Scale_Base_Key( const CEGUI::EventArgs &event )
  1590. {
  1591.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1592.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1593.  
  1594.     Set_Scale( string_to_float( str_text ), size_scale_rand );
  1595.  
  1596.     return 1;
  1597. }
  1598.  
  1599. bool cParticle_Emitter :: Editor_Scale_Rand_Key( const CEGUI::EventArgs &event )
  1600. {
  1601.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1602.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1603.  
  1604.     Set_Scale( size_scale, string_to_float( str_text ) );
  1605.  
  1606.     return 1;
  1607. }
  1608.  
  1609. bool cParticle_Emitter :: Editor_Horizontal_Gravity_Base_Key( const CEGUI::EventArgs &event )
  1610. {
  1611.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1612.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1613.  
  1614.     Set_Horizontal_Gravity( string_to_float( str_text ), gravity_x_rand );
  1615.  
  1616.     return 1;
  1617. }
  1618.  
  1619. bool cParticle_Emitter :: Editor_Horizontal_Gravity_Rand_Key( const CEGUI::EventArgs &event )
  1620. {
  1621.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1622.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1623.  
  1624.     Set_Horizontal_Gravity( gravity_x, string_to_float( str_text ) );
  1625.  
  1626.     return 1;
  1627. }
  1628.  
  1629. bool cParticle_Emitter :: Editor_Vertical_Gravity_Base_Key( const CEGUI::EventArgs &event )
  1630. {
  1631.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1632.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1633.  
  1634.     Set_Vertical_Gravity( string_to_float( str_text ), gravity_y_rand );
  1635.  
  1636.     return 1;
  1637. }
  1638.  
  1639. bool cParticle_Emitter :: Editor_Vertical_Gravity_Rand_Key( const CEGUI::EventArgs &event )
  1640. {
  1641.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1642.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  1643.  
  1644.     Set_Vertical_Gravity( gravity_y, string_to_float( str_text ) );
  1645.  
  1646.     return 1;
  1647. }
  1648.  
  1649. /* *** *** *** *** *** cAnimation_Manager *** *** *** *** *** *** *** *** *** *** *** *** */
  1650.  
  1651. cAnimation_Manager :: cAnimation_Manager( void )
  1652. : cObject_Manager<cAnimation>()
  1653. {
  1654.     
  1655. }
  1656.  
  1657. cAnimation_Manager :: ~cAnimation_Manager( void )
  1658. {
  1659.     Delete_All();
  1660. }
  1661.  
  1662. void cAnimation_Manager :: Update( void )
  1663. {
  1664.     for( AnimationList::iterator itr = objects.begin(); itr != objects.end(); )
  1665.     {
  1666.         // get object pointer
  1667.         cAnimation *obj = (*itr);
  1668.  
  1669.         // update
  1670.         obj->Update();
  1671.  
  1672.         // delete if finished
  1673.         if( !obj->visible )
  1674.         {
  1675.             itr = objects.erase( itr );
  1676.             delete obj;
  1677.         }
  1678.         // increment
  1679.         else
  1680.         {
  1681.             ++itr;
  1682.         }
  1683.     }
  1684. }
  1685.  
  1686. void cAnimation_Manager :: Draw( void )
  1687. {
  1688.     for( AnimationList::iterator itr = objects.begin(), itr_end = objects.end(); itr != itr_end; ++itr )
  1689.     {
  1690.         (*itr)->Draw();
  1691.     }
  1692. }
  1693.  
  1694. void cAnimation_Manager :: Add( cAnimation *animation )
  1695. {
  1696.     if( !animation )
  1697.     {
  1698.         return;
  1699.     }
  1700.  
  1701.     // Initialize
  1702.     animation->Init_Anim();
  1703.  
  1704.     // Add
  1705.     cObject_Manager<cAnimation>::Add( animation );
  1706. }
  1707.  
  1708. /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
  1709.  
  1710. cAnimation_Manager *pAnimation_Manager = NULL;
  1711.