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

  1. /***************************************************************************
  2.  * box.cpp  -  class for the basic box handler
  3.  *
  4.  * Copyright (C) 2003 - 2008 Florian Richter
  5.  ***************************************************************************/
  6. /*
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 3 of the License, or
  10.    (at your option) any later version.
  11.    
  12.    You should have received a copy of the GNU General Public License
  13.    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  14. */
  15.  
  16. #include "../objects/box.h"
  17. #include "../audio/audio.h"
  18. #include "../core/camera.h"
  19. #include "../core/framerate.h"
  20. #include "../level/level.h"
  21. #include "../core/game_core.h"
  22. #include "../video/animation.h"
  23. #include "../player/player.h"
  24. #include "../video/gl_surface.h"
  25. #include "../user/savegame.h"
  26. #include "../core/sprite_manager.h"
  27. #include "../core/math/utilities.h"
  28. #include "../core/i18n.h"
  29.  
  30. /* *** *** *** *** *** *** *** *** cBaseBox *** *** *** *** *** *** *** *** *** */
  31.  
  32. cBaseBox :: cBaseBox( float x /* = 0 */, float y /* = 0 */ )
  33. : cImageObjectSprite( x, y )
  34. {
  35.     type = TYPE_ACTIVESPRITE;
  36.     sprite_array = ARRAY_ACTIVE;
  37.     massivetype = MASS_MASSIVE;
  38.     can_be_ground = 1;
  39.     Set_Scale_Directions( 1, 1, 1, 1 );
  40.  
  41.     counter = 0;
  42.     anim_counter_min = 0;
  43.     anim_counter_max = 0;
  44.     box_type = TYPE_UNDEFINED;
  45.     item_image = NULL;
  46.     posz = 0.055f;
  47.  
  48.     move_col_dir = DIR_UNDEFINED;
  49.     move_counter = 0;
  50.     move_back = 0;
  51.     useable_count = 1; // default = 1 time usable
  52.     start_useable_count = 1;
  53.  
  54.     box_invisible = 0;
  55.  
  56.     particle_counter_active = 0;
  57. }
  58.  
  59. cBaseBox :: ~cBaseBox( void )
  60. {
  61.     //
  62. }
  63.  
  64. void cBaseBox :: Create_from_Stream( CEGUI::XMLAttributes &attributes )
  65. {
  66.     // position
  67.     Set_Pos( static_cast<float>(attributes.getValueAsInteger( "posx" )), static_cast<float>(attributes.getValueAsInteger( "posy" )), 1 );
  68.     if( box_type != TYPE_SPINBOX && box_type != TYPE_TEXT_BOX )
  69.     {
  70.         // animation
  71.         Set_Animation( attributes.getValueAsString( "animation", anim_type ).c_str() );
  72.     }
  73.     // invisible
  74.     Set_Invisible( attributes.getValueAsInteger( "invisible" ) );
  75.     // useable count
  76.     Set_Useable_Count( attributes.getValueAsInteger( "useable_count", start_useable_count ), 1 );
  77. }
  78.  
  79. void cBaseBox :: Save_to_Stream( ofstream &file )
  80. {
  81.     // position
  82.     file << "\t\t<Property name=\"posx\" value=\"" << static_cast<int>(startposx) << "\" />" << std::endl;
  83.     file << "\t\t<Property name=\"posy\" value=\"" << static_cast<int>(startposy) << "\" />" << std::endl;
  84.     // type
  85.     if( box_type == TYPE_SPINBOX )
  86.     {
  87.         file << "\t\t<Property name=\"type\" value=\"spin\" />" << std::endl;
  88.     }
  89.     else if( box_type == TYPE_TEXT_BOX )
  90.     {
  91.         file << "\t\t<Property name=\"type\" value=\"text\" />" << std::endl;
  92.     }
  93.     else
  94.     {
  95.         file << "\t\t<Property name=\"type\" value=\"bonus\" />" << std::endl;
  96.         // animation type
  97.         file << "\t\t<Property name=\"animation\" value=\"" << anim_type << "\" />" << std::endl;
  98.         // best possible item
  99.         file << "\t\t<Property name=\"item\" value=\"" << box_type << "\" />" << std::endl;
  100.     }
  101.     // invisible
  102.     file << "\t\t<Property name=\"invisible\" value=\"" << box_invisible << "\" />" << std::endl;
  103.     // useable count
  104.     file << "\t\t<Property name=\"useable_count\" value=\"" << start_useable_count << "\" />" << std::endl;
  105. }
  106.  
  107. void cBaseBox :: Load_from_Savegame( cSave_Level_Object *save_object )
  108. {
  109.     // useable count
  110.     int save_useable_count = string_to_int( save_object->Get_Value( "useable_count" ) );
  111.     Set_Useable_Count( save_useable_count );
  112. }
  113.  
  114. cSave_Level_Object *cBaseBox :: Save_to_Savegame( void )
  115. {
  116.     // only save if needed
  117.     if( useable_count == start_useable_count )
  118.     {
  119.         return NULL;
  120.     }
  121.  
  122.     cSave_Level_Object *save_object = new cSave_Level_Object();
  123.  
  124.     // default values
  125.     save_object->type = type;
  126.     save_object->properties.push_back( cSave_Level_Object_Property( "posx", int_to_string( static_cast<int>(startposx) ) ) );
  127.     save_object->properties.push_back( cSave_Level_Object_Property( "posy", int_to_string( static_cast<int>(startposy) ) ) );
  128.  
  129.     // Useable Count
  130.     save_object->properties.push_back( cSave_Level_Object_Property( "useable_count", int_to_string( useable_count ) ) );
  131.  
  132.     return save_object;
  133. }
  134.  
  135. void cBaseBox :: Set_Animation( string new_anim_type )
  136. {
  137.     // already set
  138.     if( anim_type.compare( new_anim_type ) == 0 )
  139.     {
  140.         return;
  141.     }
  142.  
  143.     Clear_Images();
  144.     anim_type = new_anim_type;
  145.  
  146.     if( anim_type.compare( "Bonus" ) == 0 )
  147.     {
  148.         // disabled image
  149.         images.push_back( pVideo->Get_Surface( "game/box/brown1_1.png" ) );
  150.         // animation images
  151.         images.push_back( pVideo->Get_Surface( "game/box/yellow/bonus/1.png" ) );
  152.         images.push_back( pVideo->Get_Surface( "game/box/yellow/bonus/2.png" ) );
  153.         images.push_back( pVideo->Get_Surface( "game/box/yellow/bonus/3.png" ) );
  154.         images.push_back( pVideo->Get_Surface( "game/box/yellow/bonus/4.png" ) );
  155.         images.push_back( pVideo->Get_Surface( "game/box/yellow/bonus/5.png" ) );
  156.         images.push_back( pVideo->Get_Surface( "game/box/yellow/bonus/6.png" ) );
  157.  
  158.         anim_counter_min = 1;
  159.         anim_counter_max = 6;
  160.     }
  161.     else if( anim_type.compare( "Default" ) == 0 )
  162.     {
  163.         // disabled image
  164.         images.push_back( pVideo->Get_Surface( "game/box/brown1_1.png" ) );
  165.         // default
  166.         images.push_back( pVideo->Get_Surface( "game/box/yellow/default.png" ) );
  167.  
  168.         anim_counter_min = 1;
  169.         anim_counter_max = 1;
  170.     }
  171.     else if( anim_type.compare( "Power" ) == 0 )
  172.     {
  173.         // disabled image
  174.         images.push_back( pVideo->Get_Surface( "game/box/brown1_1.png" ) );
  175.         // default
  176.         images.push_back( pVideo->Get_Surface( "game/box/yellow/power_1.png" ) );
  177.  
  178.         anim_counter_min = 1;
  179.         anim_counter_max = 1;
  180.     }
  181.     else if( anim_type.compare( "Spin" ) == 0 )
  182.     {
  183.         // disabled image
  184.         images.push_back( pVideo->Get_Surface( "game/box/yellow/spin/disabled.png" ) );
  185.         // animation images
  186.         images.push_back( pVideo->Get_Surface( "game/box/yellow/default.png" ) );
  187.         images.push_back( pVideo->Get_Surface( "game/box/yellow/spin/1.png" ) );
  188.         images.push_back( pVideo->Get_Surface( "game/box/yellow/spin/2.png" ) );
  189.         images.push_back( pVideo->Get_Surface( "game/box/yellow/spin/3.png" ) );
  190.         images.push_back( pVideo->Get_Surface( "game/box/yellow/spin/4.png" ) );
  191.         images.push_back( pVideo->Get_Surface( "game/box/yellow/spin/5.png" ) );
  192.  
  193.         anim_counter_min = 1;
  194.         anim_counter_max = 6;
  195.     }
  196.     else
  197.     {
  198.         printf( "Warning : Unknown Box Animation Type %s\n", anim_type.c_str() );
  199.         Set_Animation( "Bonus" );
  200.     }
  201.  
  202.     counter = static_cast<float>(anim_counter_min);
  203.     Set_Image( static_cast<int>(counter), 1, 0 );
  204. }
  205.  
  206. void cBaseBox :: Set_Useable_Count( int count, bool new_startcount /* = 0 */ )
  207. {
  208.     // unlimited
  209.     if( count < -1 )
  210.     {
  211.         count = -1;
  212.     }
  213.  
  214.     useable_count = count;
  215.  
  216.     if( new_startcount )
  217.     {
  218.         start_useable_count = useable_count;
  219.     }
  220. }
  221.  
  222. void cBaseBox :: Set_Invisible( unsigned int type )
  223. {
  224.     // already set
  225.     if( box_invisible == type )
  226.     {
  227.         return;
  228.     }
  229.  
  230.     // was invisible
  231.     if( box_invisible == 1 )
  232.     {
  233.         Set_Image( static_cast<int>(counter), 1, 0 );
  234.     }
  235.     // was ghost
  236.     else if( box_invisible == 2 )
  237.     {
  238.         Set_Color( 255, 255, 255, 255 );
  239.         Set_Color_Combine( 0, 0, 0, 0 );
  240.     }
  241.  
  242.     // got invisible
  243.     if( type == 1 )
  244.     {
  245.         Set_Image( -1, 1, 0 );
  246.  
  247.         col_pos = images[0]->col_pos;
  248.         col_rect.w = images[0]->col_w;
  249.         col_rect.h = images[0]->col_h;
  250.         rect.w = images[0]->col_w;
  251.         rect.h = images[0]->col_h;
  252.         start_rect.w = images[0]->col_w;
  253.         start_rect.h = images[0]->col_h;
  254.     }
  255.     // got ghost
  256.     else if( type == 2 )
  257.     {
  258.         Set_Color( 192, 192, 255, 128 );
  259.         Set_Color_Combine( 0.2f, 0.2f, 0.55f, GL_ADD );
  260.     }
  261.  
  262.     box_invisible = type;
  263.  
  264.     // create name again
  265.     Create_Name();
  266. }
  267.  
  268. void cBaseBox :: Activate_Collision( ObjectDirection cdirection )
  269. {
  270.     // if already active ignore event
  271.     if( move_col_dir != DIR_UNDEFINED )
  272.     {
  273.         return;
  274.     }
  275.  
  276.     // not useable
  277.     if( useable_count == 0 )
  278.     {
  279.         return;
  280.     }
  281.  
  282.     // if invisible go visible
  283.     if( box_invisible )
  284.     {
  285.         Set_Image( static_cast<int>(counter), 0, 0 );
  286.     }
  287.  
  288.     // set scaling based on direction
  289.     if( cdirection == DIR_UP )
  290.     {
  291.         Set_Scale_Directions( 1, 0, 1, 1 );
  292.     }
  293.     else if( cdirection == DIR_DOWN )
  294.     {
  295.         Set_Scale_Directions( 0, 1, 1, 1 );
  296.     }
  297.     else if( cdirection == DIR_LEFT )
  298.     {
  299.         Set_Scale_Directions( 1, 0, 1, 0 );
  300.     }
  301.     else if( cdirection == DIR_RIGHT )
  302.     {
  303.         Set_Scale_Directions( 1, 0, 0, 1 );
  304.     }
  305.  
  306.     // set collision direction
  307.     move_col_dir = cdirection;
  308.     Update_Valid_Update();
  309.  
  310.     Check_Collision( Get_Opposite_Direction( move_col_dir ) );
  311.     Activate();
  312.  
  313.     // set useable count
  314.     if( useable_count > 0 )
  315.     {
  316.         Set_Useable_Count( useable_count - 1 );
  317.     }
  318. }
  319.  
  320. void cBaseBox :: Update_Collision( void )
  321. {
  322.     // not moving
  323.     if( move_col_dir == DIR_UNDEFINED )
  324.     {
  325.         return;
  326.     }
  327.  
  328.     // invalid direction
  329.     if( move_col_dir != DIR_UP && move_col_dir != DIR_DOWN && move_col_dir != DIR_RIGHT && move_col_dir != DIR_LEFT )
  330.     {
  331.         printf( "Warning : wrong box collision direction %d\n", move_col_dir );
  332.         move_col_dir = DIR_UNDEFINED;
  333.         Update_Valid_Update();
  334.         return;
  335.     }
  336.  
  337.     // speed mod
  338.     float mod = pFramerate->speedfactor * 0.05f;
  339.     // counter
  340.     move_counter += pFramerate->speedfactor * 0.2f;
  341.  
  342.     // move into the given direction
  343.     if( !move_back )
  344.     {
  345.         // scale
  346.         Add_Scale( mod );
  347.  
  348.         // Particles
  349.         Generate_Activation_Particles();
  350.  
  351.         // check if reached final position
  352.         if( move_counter > 1 )
  353.         {
  354.             move_back = 1;
  355.             move_counter = 0;
  356.         }
  357.     }
  358.     // move back to the original position
  359.     else
  360.     {
  361.         // scale
  362.         Add_Scale( -mod );
  363.  
  364.         // check if reached original position
  365.         if(    move_counter > 1 )
  366.         {
  367.             move_col_dir = DIR_UNDEFINED;
  368.             Update_Valid_Update();
  369.             move_back = 0;
  370.             move_counter = 0;
  371.  
  372.             // reset rect
  373.             col_pos = image->col_pos;
  374.             // reset scale
  375.             Set_Scale( 1 );
  376.             Set_Scale_Directions( 1, 1, 1, 1 );
  377.             // reset position
  378.             Set_Pos( startposx, startposy );
  379.         }
  380.     }
  381. }
  382.  
  383. void cBaseBox :: Check_Collision( ObjectDirection cdirection )
  384. {
  385.     // additional direction based check position
  386.     float check_x = 0;
  387.     float check_y = 0;
  388.  
  389.  
  390.     // set the collision size based on the collision direction
  391.     if( cdirection == DIR_BOTTOM )
  392.     {
  393.         check_y -= 10;
  394.     }
  395.     else if( cdirection == DIR_TOP )
  396.     {
  397.         check_y += 10;
  398.     }
  399.     else if( cdirection == DIR_LEFT ) 
  400.     {
  401.         check_x += 5;
  402.     }
  403.     else if( cdirection == DIR_RIGHT )
  404.     {
  405.         check_x -= 5;
  406.     }
  407.  
  408.     // collision count
  409.     unsigned int col_count = Collision_Check_Relative( check_x, check_y, col_rect.w - ( check_x * 0.5f ), col_rect.h - ( check_y * 0.5f ) ).size();
  410.  
  411.     // handle collisions
  412.     for( unsigned int i = 0; i < col_count; i++ )
  413.     {
  414.         cObjectCollision *col = Collision_Get_last();
  415.         cSprite *col_obj = pActive_Sprite_Manager->Get_Pointer( col->number );
  416.  
  417.         // send box collision
  418.         col_obj->Handle_Collision_Box( Get_Opposite_Direction( col->direction ), &col_rect );
  419.  
  420.         // Enemy collision
  421.         if( col->type == CO_ENEMY )
  422.         {
  423.             Col_Enemy( col_obj );
  424.         }
  425.  
  426.         Collision_Delete( col );
  427.     }
  428. }
  429.  
  430. void cBaseBox :: Col_Enemy( cSprite *obj )
  431. {
  432.     // todo : handle this on enemy class Handle_Collision_Box()
  433.     // only valid enemies
  434.     if( obj->type == TYPE_FURBALL || obj->type == TYPE_TURTLE || obj->type == TYPE_KRUSH )
  435.     {
  436.         pAudio->Play_Sound( "death_box.ogg" );
  437.         static_cast<cMovingSprite *>(obj)->DownGrade( 1 );
  438.     }
  439. }
  440.  
  441. void cBaseBox :: Activate( void )
  442. {
  443.     // virtual
  444. }
  445.  
  446. void cBaseBox :: Update( void )
  447. {
  448.     // animate visible box only or an activated invisible box
  449.     if( !box_invisible || image )
  450.     {
  451.         // Spinbox uses anim_counter for animation handling
  452.         if( ( type == TYPE_SPINBOX || useable_count != 0 ) && anim_counter_min != anim_counter_max )
  453.         {
  454.             counter += pFramerate->speedfactor * 0.4f;
  455.  
  456.             if( counter >= anim_counter_max + 1 )
  457.             {
  458.                 counter = static_cast<float>(anim_counter_min);
  459.             }
  460.  
  461.             // Set_Image overwrites col_pos
  462.             GL_point col_pos_temp = col_pos;
  463.  
  464.             Set_Image( static_cast<int>(counter) );
  465.  
  466.             // save col_pos
  467.             col_pos = col_pos_temp;
  468.         }
  469.     }
  470.  
  471.     Update_Collision();
  472. }
  473.  
  474. void cBaseBox :: Draw( cSurfaceRequest *request /* = NULL */ )
  475. {
  476.     if( !valid_draw )
  477.     {
  478.         return;
  479.     }
  480.  
  481.     // editor disabled
  482.     if( !editor_level_enabled )
  483.     {
  484.         // visible box or activated invisible box
  485.         cImageObjectSprite::Draw( request );
  486.     }
  487.     // editor enabled
  488.     else
  489.     {
  490.         // draw invisible box only in editor mode
  491.         if( box_invisible )
  492.         {
  493.             Color color;
  494.  
  495.             // default invisible
  496.             if( box_invisible == 1 )
  497.             {
  498.                 color = Color( static_cast<Uint8>(240), 0, 30, 128 );
  499.             }
  500.             // ghost
  501.             else if( box_invisible == 2 )
  502.             {
  503.                 color = Color( static_cast<Uint8>(20), 20, 150, 128 );
  504.             }
  505.  
  506.             pVideo->Draw_Rect( startposx - pActive_Camera->x, startposy - pActive_Camera->y, col_rect.w, col_rect.h, posz, &color );
  507.         }
  508.         // visible box
  509.         else
  510.         {
  511.             cImageObjectSprite::Draw( request );
  512.         }
  513.  
  514.         // draw item image
  515.         if( item_image )
  516.         {
  517.             // auto position
  518.             item_image->Blit( startposx - ( ( item_image->w - rect.w ) / 2 ) - pActive_Camera->x, startposy - ( ( item_image->h - rect.h ) / 2 ) - pActive_Camera->y, posz + 0.000003f );
  519.         }
  520.     }
  521. }
  522.  
  523. void cBaseBox :: Generate_Activation_Particles( void )
  524. {
  525.     // no default/unimportant boxes
  526.     if( type == TYPE_SPINBOX || type == TYPE_TEXT_BOX || box_type == TYPE_GOLDPIECE )
  527.     {
  528.         return;
  529.     }
  530.  
  531.     particle_counter_active += pFramerate->speedfactor;
  532.  
  533.     while( particle_counter_active > 0 )
  534.     {
  535.         cParticle_Emitter *anim = new cParticle_Emitter();
  536.         anim->Set_Pos( posx + Get_Random_Float( 0, rect.w ), posy );
  537.         anim->Set_Direction_Range( 180, 180 );
  538.         anim->Set_Speed( 3.1f, 0.5f );
  539.         anim->Set_Scale( 0.7f, 0.1f );
  540.  
  541.         Color color = white;
  542.  
  543.         if( box_type == TYPE_MUSHROOM_DEFAULT )
  544.         {
  545.             color = Color( static_cast<Uint8>( 100 + ( rand() % 100 ) ), 20 + ( rand() % 50 ), 10 + ( rand() % 30 ) );
  546.         }
  547.         else if( box_type == TYPE_FIREPLANT )
  548.         {
  549.             color = Color( static_cast<Uint8>( 110 + ( rand() % 150 ) ), rand() % 50, rand() % 30 );
  550.         }
  551.         else if( box_type == TYPE_MUSHROOM_BLUE )
  552.         {
  553.             color = Color( static_cast<Uint8>( rand() % 30 ), ( rand() % 30 ), 150 + ( rand() % 50 ) );
  554.         }
  555.         else if( box_type == TYPE_MUSHROOM_GHOST )
  556.         {
  557.             color = Color( static_cast<Uint8>( 100 + ( rand() % 50 ) ), 100 + ( rand() % 50 ), 100 + ( rand() % 50 ) );
  558.         }
  559.         else if( box_type == TYPE_MUSHROOM_LIVE_1 )
  560.         {
  561.             color = Color( static_cast<Uint8>( rand() % 30 ), 100 + ( rand() % 150 ), rand() % 30 );
  562.         }
  563.         else if( box_type == TYPE_JSTAR )
  564.         {
  565.             color = Color( static_cast<Uint8>( 110 + ( rand() % 150 ) ), 80 + ( rand() % 50 ), rand() % 20 );
  566.         }
  567.         else if( box_type == TYPE_MUSHROOM_POISON )
  568.         {
  569.             color = Color( static_cast<Uint8>( 50 + rand() % 50 ), 100 + ( rand() % 150 ), rand() % 10 );
  570.         }
  571.  
  572.         anim->Set_Time_to_Live( 0.3f );
  573.         anim->Set_Color( color );
  574.         anim->Set_Blending( BLEND_ADD );
  575.         anim->Set_Image( pVideo->Get_Surface( "animation/particles/light.png" ) );
  576.         pAnimation_Manager->Add( anim );
  577.  
  578.         particle_counter_active--;
  579.     }
  580. }
  581.  
  582. bool cBaseBox :: Is_Update_Valid( void )
  583. {
  584.     // if not activateable and not animating
  585.     if( !useable_count && move_col_dir == DIR_UNDEFINED )
  586.     {
  587.         return 0;
  588.     }
  589.  
  590.     // if not visible
  591.     if( !visible )
  592.     {
  593.         return 0;
  594.     }
  595.  
  596.     return 1;
  597. }
  598.  
  599. bool cBaseBox :: Is_Draw_Valid( void )
  600. {
  601.     // if editor not enabled
  602.     if( !editor_enabled )
  603.     {
  604.         // not visible
  605.         if( !visible || !image )
  606.         {
  607.             return 0;
  608.         }
  609.  
  610.         // ghost
  611.         if( box_invisible == 2 )
  612.         {
  613.             // maryo is not ghost
  614.             if( pPlayer->maryo_type != MARYO_GHOST )
  615.             {
  616.                 return 0;
  617.             }
  618.         }
  619.     }
  620.     // editor enabled
  621.     else
  622.     {
  623.         // no image
  624.         if( !start_image && !box_invisible )
  625.         {
  626.             return 0;
  627.         }
  628.     }
  629.  
  630.     // not visible on the screen
  631.     if( !Is_Visible_on_Screen() )
  632.     {
  633.         return 0;
  634.     }
  635.  
  636.     return 1;
  637. }
  638.  
  639. unsigned int cBaseBox :: Validate_Collision( cSprite *obj )
  640. {
  641.     if( obj->massivetype == MASS_MASSIVE )
  642.     {
  643.         return 2;
  644.     }
  645.     // items
  646.     if( obj->type == TYPE_MUSHROOM_LIVE_1 || obj->type == TYPE_MUSHROOM_DEFAULT || obj->type == TYPE_MUSHROOM_POISON 
  647.         || obj->type == TYPE_MUSHROOM_BLUE || obj->type == TYPE_MUSHROOM_GHOST || obj->type == TYPE_FGOLDPIECE )
  648.     {
  649.         return 2;
  650.     }
  651.     if( obj->massivetype == MASS_HALFMASSIVE )
  652.     {
  653.         // if moving downwards and object is on top
  654.         if( vely >= 0 && Is_on_Top( obj ) )
  655.         {
  656.             return 2;
  657.         }
  658.     }
  659.  
  660.     return 0;
  661. }
  662.  
  663. void cBaseBox :: Handle_Collision_Player( cObjectCollision *collision )
  664. {
  665.     // if player jumps from below or fly's against it
  666.     if( collision->direction == DIR_BOTTOM && pPlayer->state != STA_FLY )
  667.     {
  668.         if( useable_count != 0 )
  669.         {
  670.             Activate_Collision( Get_Opposite_Direction( collision->direction ) );
  671.         }
  672.         else
  673.         {
  674.             if( Is_Visible_on_Screen() )
  675.             {
  676.                 pAudio->Play_Sound( "tock.ogg" );
  677.             }
  678.         }
  679.     }
  680. }
  681.  
  682. void cBaseBox :: Handle_Collision_Enemy( cObjectCollision *collision )
  683. {
  684.     if( collision->direction == DIR_RIGHT || collision->direction == DIR_LEFT || collision->direction == DIR_BOTTOM )
  685.     {
  686.         if( useable_count != 0 )
  687.         {
  688.             Activate_Collision( Get_Opposite_Direction( collision->direction ) );
  689.         }
  690.         else
  691.         {
  692.             if( Is_Visible_on_Screen() )
  693.             {
  694.                 pAudio->Play_Sound( "tock.ogg" );
  695.             }
  696.         }
  697.     }
  698. }
  699.  
  700.  
  701. void cBaseBox :: Editor_Activate( void )
  702. {
  703.     CEGUI::WindowManager &wmgr = CEGUI::WindowManager::getSingleton();
  704.  
  705.     if( type != TYPE_TEXT_BOX )
  706.     {
  707.         // useable count
  708.         CEGUI::Editbox *editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "editor_basebox_useable_count" ));
  709.         Editor_Add( UTF8_("Useable Count"), UTF8_("Useable Count"), editbox, 80 );
  710.  
  711.         editbox->setText( int_to_string( start_useable_count ) );
  712.         editbox->subscribeEvent( CEGUI::Editbox::EventKeyUp, CEGUI::Event::Subscriber( &cBaseBox::Editor_Useable_Count_Key, this ) );
  713.     }
  714.  
  715.     // Invisible
  716.     CEGUI::Combobox *combobox = static_cast<CEGUI::Combobox *>(wmgr.createWindow( "TaharezLook/Combobox", "editor_basebox_invisible" ));
  717.     Editor_Add( UTF8_("Invisible"), UTF8_("Invisible until activated or if ghost only visible if in ghost mode."), combobox, 120, 100 );
  718.  
  719.     combobox->addItem( new CEGUI::ListboxTextItem( UTF8_("Enabled") ) );
  720.     combobox->addItem( new CEGUI::ListboxTextItem( UTF8_("Disabled") ) );
  721.     combobox->addItem( new CEGUI::ListboxTextItem( UTF8_("Ghost") ) );
  722.  
  723.     if( box_invisible == 1 )
  724.     {
  725.         combobox->setText( UTF8_("Enabled") );
  726.     }
  727.     else if( box_invisible == 2 )
  728.     {
  729.         combobox->setText( UTF8_("Ghost") );
  730.     }
  731.     else
  732.     {
  733.         combobox->setText( UTF8_("Disabled") );
  734.     }
  735.  
  736.     combobox->subscribeEvent( CEGUI::Combobox::EventListSelectionAccepted, CEGUI::Event::Subscriber( &cBaseBox::Editor_Invisible_Select, this ) );
  737.  
  738.     if( type == TYPE_SPINBOX )
  739.     {
  740.         // init
  741.         Editor_Init();
  742.     }
  743. }
  744.  
  745. bool cBaseBox :: Editor_Useable_Count_Key( const CEGUI::EventArgs &event )
  746. {
  747.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  748.     string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
  749.  
  750.     Set_Useable_Count( string_to_int( str_text ), 1 );
  751.  
  752.     return 1;
  753. }
  754.  
  755. bool cBaseBox :: Editor_Invisible_Select( const CEGUI::EventArgs &event )
  756. {
  757.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  758.     CEGUI::ListboxItem *item = static_cast<CEGUI::Combobox *>( windowEventArgs.window )->getSelectedItem();
  759.  
  760.     if( item->getText().compare( UTF8_("Enabled") ) == 0 )
  761.     {
  762.         Set_Invisible( 1 );
  763.     }
  764.     else if( item->getText().compare( UTF8_("Ghost") ) == 0 )
  765.     {
  766.         Set_Invisible( 2 );
  767.     }
  768.     else
  769.     {
  770.         Set_Invisible( 0 );
  771.     }
  772.  
  773.     return 1;
  774. }
  775.  
  776. void cBaseBox :: Create_Name( void )
  777. {
  778.     if( box_type == TYPE_UNDEFINED )
  779.     {
  780.         name = _("Box Empty");
  781.     }
  782.     else if( box_type == TYPE_POWERUP )
  783.     {
  784.         name = _("Box Random");
  785.     }
  786.     else if( box_type == TYPE_SPINBOX )
  787.     {
  788.         name = _("Spinbox");
  789.     }
  790.     else if( box_type == TYPE_TEXT_BOX )
  791.     {
  792.         name = _("Textbox");
  793.     }
  794.     else if( box_type == TYPE_MUSHROOM_DEFAULT )
  795.     {
  796.         name = _("Box Mushroom");
  797.     }
  798.     else if( box_type == TYPE_FIREPLANT )
  799.     {
  800.         name = _("Box Mushroom - Fireplant");
  801.     }
  802.     else if( box_type == TYPE_MUSHROOM_BLUE )
  803.     {
  804.         name = _("Box Mushroom - Blue Mushroom");
  805.     }
  806.     else if( box_type == TYPE_MUSHROOM_GHOST )
  807.     {
  808.         name = _("Box Mushroom - Ghost Mushroom");
  809.     }
  810.     else if( box_type == TYPE_MUSHROOM_LIVE_1 )
  811.     {
  812.         name = _("Box 1-UP");
  813.     }
  814.     else if( box_type == TYPE_JSTAR )
  815.     {
  816.         name = _("Box Star");
  817.     }
  818.     else if( box_type == TYPE_GOLDPIECE )
  819.     {
  820.         name = _("Box Goldpiece");
  821.     }
  822.     else if( box_type == TYPE_MUSHROOM_POISON )
  823.     {
  824.         name = _("Box Mushroom Poison");
  825.     }
  826.     else
  827.     {
  828.         name = _("Box Unknown Item Type");
  829.     }
  830.  
  831.     if( box_invisible )
  832.     {
  833.         name.insert( 0, _("Invisible ") );
  834.     }
  835. }
  836.