home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************
- * layer.cpp - Overworld Layer class
- *
- * Copyright (C) 2003 - 2008 Florian Richter
- ***************************************************************************/
- /*
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
- #include "../overworld/world_layer.h"
- #include "../video/renderer.h"
- #include "../core/game_core.h"
- #include "../core/camera.h"
- #include "../overworld/overworld.h"
- #include "../core/sprite_manager.h"
- #include "../core/i18n.h"
-
- /* *** *** *** *** *** *** *** *** Layer Line Point *** *** *** *** *** *** *** *** *** */
-
- cLayer_Line_Point :: cLayer_Line_Point( SpriteType ntype )
- : cSprite()
- {
- sprite_array = ARRAY_PASSIVE;
- type = ntype;
- massivetype = MASS_PASSIVE;
- posz = 0.087f;
-
- if( type == TYPE_OW_LINE_START )
- {
- posz += 0.001f;
- color = orange;
- name = _("Line Start Point");
- }
- else
- {
- color = red;
- name = _("Line End Point");
- }
-
- rect.w = 4;
- rect.h = 4;
- col_rect.w = rect.w;
- col_rect.h = rect.h;
- start_rect.w = rect.w;
- start_rect.h = rect.h;
-
- Update_Position_Rect();
-
- player_range = 0;
- }
-
- cLayer_Line_Point :: ~cLayer_Line_Point( void )
- {
-
- }
-
- void cLayer_Line_Point :: Draw( cSurfaceRequest *request /* = NULL */ )
- {
- if( !pOverworld_Manager->draw_layer )
- {
- return;
- }
-
- // point rect
- pVideo->Draw_Rect( col_rect.x - pActive_Camera->x, col_rect.y - pActive_Camera->y, col_rect.w, col_rect.h, posz, &color );
- }
-
- void cLayer_Line_Point :: Editor_Activate( void )
- {
- CEGUI::WindowManager &wmgr = CEGUI::WindowManager::getSingleton();
-
- // origin
- CEGUI::Editbox *editbox = static_cast<CEGUI::Editbox *>(wmgr.createWindow( "TaharezLook/Editbox", "layer_line_origin" ));
- Editor_Add( UTF8_("Waypoint origin"), UTF8_("Waypoint origin"), editbox, 100 );
-
- editbox->setText( int_to_string( static_cast<cLayer_Line *>(line)->origin ) );
- editbox->subscribeEvent( CEGUI::Editbox::EventKeyUp, CEGUI::Event::Subscriber( &cLayer_Line_Point::Editor_Origin_Key, this ) );
-
- // init
- Editor_Init();
- }
-
- bool cLayer_Line_Point :: Editor_Origin_Key( const CEGUI::EventArgs &event )
- {
- const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
- string str_text = static_cast<CEGUI::Editbox *>( windowEventArgs.window )->getText().c_str();
-
- static_cast<cLayer_Line *>(line)->origin = string_to_int( str_text );
-
- return 1;
- }
-
- float cLayer_Line_Point :: Get_Line_Pos_X( void )
- {
- return posx + ( col_rect.w * 0.5f );
- }
-
- float cLayer_Line_Point :: Get_Line_Pos_Y( void )
- {
- return posy + ( col_rect.h * 0.5f );
- }
-
- /* *** *** *** *** *** *** *** *** Layer Line *** *** *** *** *** *** *** *** *** */
-
- cLayer_Line :: cLayer_Line( void )
- {
- anim_type = 0;
- origin = 0;
-
- start = new cLayer_Line_Point( TYPE_OW_LINE_START );
- start->line = (void *)this;
- pActive_Overworld->sprite_manager->Add( start );
-
-
- end = new cLayer_Line_Point( TYPE_OW_LINE_END );
- end->line = (void *)this;
- pActive_Overworld->sprite_manager->Add( end );
- }
-
- cLayer_Line :: ~cLayer_Line( void )
- {
- // delete points
- pActive_Overworld->sprite_manager->Delete( start, 1 );
- pActive_Overworld->sprite_manager->Delete( end, 1 );
- }
-
- void cLayer_Line :: Draw( void )
- {
- // create request
- cLineRequest *line_request = new cLineRequest();
-
- // drawing color
- Color color = darkgreen;
-
- // if active
- if( pOverworld_Player->current_line >= 0 && pActive_Overworld->pLayer->objects[pOverworld_Player->current_line] == this )
- {
- color = lightblue;
- }
-
- pVideo->Draw_Line( start->Get_Line_Pos_X() - pActive_Camera->x, start->Get_Line_Pos_Y() - pActive_Camera->y, end->Get_Line_Pos_X() - pActive_Camera->x, end->Get_Line_Pos_Y() - pActive_Camera->y, 0.085f, &color, line_request );
- line_request->line_width = 6;
-
- // add request
- pRenderer->Add( line_request );
- }
-
- GL_line cLayer_Line :: Get_Line( void )
- {
- return GL_line( start->posx + ( start->col_rect.w * 0.5f ), start->posy + ( start->col_rect.h * 0.5f ), end->posx + ( end->col_rect.w * 0.5f ), end->posy + ( end->col_rect.h * 0.5f ) );
- }
-
- cWaypoint *cLayer_Line :: Get_End_Waypoint( void )
- {
- int wp_num = pActive_Overworld->Get_Waypoint_Collision( &end->col_rect );
- // no waypoint collision
- if( wp_num < 0 )
- {
- cLayer_Line *line_col = pActive_Overworld->pLayer->Get_Line_Collision_Start( &end->col_rect );
-
- // line collision
- if( line_col )
- {
- // follow line
- return line_col->Get_End_Waypoint();
- }
- }
-
- // return Waypoint
- return pActive_Overworld->Get_Waypoint( wp_num );
- }
-
- /* *** *** *** *** *** *** *** *** Line Collision *** *** *** *** *** *** *** *** *** */
-
- cLine_collision :: cLine_collision( void )
- {
- line = NULL;
- line_number = -2;
- difference = 0;
- }
-
- /* *** *** *** *** *** *** *** *** Near Line Collision *** *** *** *** *** *** *** *** *** */
-
- cNearLine_collision :: cNearLine_collision( void )
- {
- line_number = -2;
- start = 0;
- }
-
- /* *** *** *** *** *** *** *** *** Contact Collision *** *** *** *** *** *** *** *** *** */
-
- void cContact_collision :: clear( void )
- {
- contact = 0;
- line_hor = cLine_collision();
- line_ver = cLine_collision();
- }
-
- int cContact_collision :: Get_Best_Line( ObjectDirection dir )
- {
- // favor vertical
- if( dir == DIR_LEFT || dir == DIR_RIGHT )
- {
- if( line_ver.line_number >= 0 && line_ver.difference < line_hor.difference )
- {
- return line_ver.line_number;
- }
- else if( line_hor.line_number >= 0 )
- {
- return line_hor.line_number;
- }
- else
- {
- return line_ver.line_number;
- }
- }
- // favor horizontal
- else if( dir == DIR_UP || dir == DIR_DOWN )
- {
- if( line_hor.line_number >= 0 && line_hor.difference < line_ver.difference )
- {
- return line_hor.line_number;
- }
- else if( line_ver.line_number >= 0 )
- {
- return line_ver.line_number;
- }
- else
- {
- return line_hor.line_number;
- }
- }
-
- return -2;
- }
-
- /* *** *** *** *** *** *** *** *** Layer *** *** *** *** *** *** *** *** *** */
-
- cLayer :: cLayer( void )
- {
-
- }
-
- cLayer :: ~cLayer( void )
- {
- Delete_All();
- }
-
- void cLayer :: Load( string filename )
- {
- Delete_All();
-
- try
- {
- // parse layer
- CEGUI::System::getSingleton().getXMLParser()->parseXMLFile( *this, filename.c_str(), DATA_DIR "/" GAME_SCHEMA_DIR "/World/Lines.xsd", "" );
- }
- // catch CEGUI Exceptions
- catch( CEGUI::Exception &ex )
- {
- printf( "Loading Line Layer %s CEGUI Exception %s\n", filename.c_str(), ex.getMessage().c_str() );
- debugdisplay->Set_Text( _("Line Layer Loading failed : ") + (string)ex.getMessage().c_str() );
- }
- }
-
- bool cLayer :: Save( string filename )
- {
- ofstream file( filename.c_str(), ios::out | ios::trunc );
-
- if( !file )
- {
- debugdisplay->Set_Text( _("Couldn't save world layer ") + filename );
- return 0;
- }
-
- // xml info
- file << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
- // begin layer
- file << "<layer>" << std::endl;
-
- // lines
- for( LayerLineList::iterator itr = objects.begin(), itr_end = objects.end(); itr != itr_end; ++itr )
- {
- cLayer_Line *line = (*itr);
-
- // begin line
- file << "\t<line>" << std::endl;
- // start
- file << "\t\t<Property name=\"X1\" value=\"" << static_cast<int>(line->start->Get_Line_Pos_X()) << "\" />" << std::endl;
- file << "\t\t<Property name=\"Y1\" value=\"" << static_cast<int>(line->start->Get_Line_Pos_Y()) << "\" />" << std::endl;
- // end
- file << "\t\t<Property name=\"X2\" value=\"" << static_cast<int>(line->end->Get_Line_Pos_X()) << "\" />" << std::endl;
- file << "\t\t<Property name=\"Y2\" value=\"" << static_cast<int>(line->end->Get_Line_Pos_Y()) << "\" />" << std::endl;
- // origin
- file << "\t\t<Property name=\"origin\" value=\"" << line->origin << "\" />" << std::endl;
- // end line
- file << "\t</line>" << std::endl;
- }
-
- // end layer
- file << "</layer>" << std::endl;
- file.close();
-
- return 1;
- }
-
- void cLayer :: Draw( void )
- {
- if( !pOverworld_Manager->draw_layer )
- {
- return;
- }
-
- for( LayerLineList::iterator itr = objects.begin(), itr_end = objects.end(); itr != itr_end; ++itr )
- {
- // draw line
- (*itr)->Draw();
- }
- }
-
- cLayer_Line *cLayer :: Get_Line_Collision_Start( GL_rect *line_rect )
- {
- for( LayerLineList::iterator itr = objects.begin(), itr_end = objects.end(); itr != itr_end; ++itr )
- {
- // get pointer
- cLayer_Line *layer_line = (*itr);
-
- // check line 1
- if( Col_Box( line_rect, &layer_line->start->col_rect ) )
- {
- return layer_line;
- }
- }
-
- return NULL;
- }
-
- cLine_collision cLayer :: Get_Line_Collision_Direction( float x, float y, ObjectDirection dir, float dir_size /* = 10 */, unsigned int check_size /* = 10 */ )
- {
- if( dir == DIR_UP )
- {
- y -= dir_size;
- }
- else if( dir == DIR_DOWN )
- {
- y += dir_size;
- }
- else if( dir == DIR_RIGHT )
- {
- x += dir_size;
- }
- else if( dir == DIR_LEFT )
- {
- x -= dir_size;
- }
-
- if( dir == DIR_LEFT || dir == DIR_RIGHT )
- {
- return pActive_Overworld->pLayer->Get_Nearest( x, y, DIR_VERTICAL, check_size );
- }
- else if( dir == DIR_UP || dir == DIR_DOWN )
- {
- return pActive_Overworld->pLayer->Get_Nearest( x, y, DIR_HORIZONTAL, check_size );
- }
-
- // invalid direction
- return cLine_collision();
- }
-
- cLine_collision cLayer :: Get_Nearest( float x, float y, ObjectDirection dir /* = DIR_HORIZONTAL */, unsigned int check_size /* = 15 */, int only_origin_id /* = -1 */ )
- {
- for( LayerLineList::iterator itr = objects.begin(), itr_end = objects.end(); itr != itr_end; ++itr )
- {
- // get pointer
- cLayer_Line *layer_line = (*itr);
-
- // line is not from waypoint
- if( only_origin_id >= 0 && only_origin_id != layer_line->origin )
- {
- continue;
- }
-
- cLine_collision col = Get_Nearest_Line( layer_line, x, y, dir, check_size );
-
- // found
- if( col.line )
- {
- return col;
- }
- }
-
- // none found
- return cLine_collision();
- }
-
- cLine_collision cLayer :: Get_Nearest_Line( cLayer_Line *map_layer_line, float x, float y, ObjectDirection dir /* = DIR_HORIZONTAL */, unsigned int check_size /* = 15 */ )
- {
- GL_line line_1, line_2;
-
- // create map line
- GL_line map_line = map_layer_line->Get_Line();
-
- // check into both directions from inside
- for( float csize = 0; csize < check_size; csize++ )
- {
- line_1.x1 = x;
- line_1.y1 = y;
- line_1.x2 = x;
- line_1.y2 = y;
- line_2 = line_1;
-
- // set line size
- if( dir == DIR_HORIZONTAL )
- {
- line_1.x1 += csize;
- line_2.x2 -= csize;
- }
- else // vertical
- {
- line_1.y1 += csize;
- line_2.y2 -= csize;
- }
-
- // debug drawing
- if( pOverworld_Manager->debugmode && pOverworld_Manager->draw_layer )
- {
- // create request
- cLineRequest *line_request = new cLineRequest();
- pVideo->Draw_Line( line_1.x1 - pActive_Camera->x, line_1.y1 - pActive_Camera->y, line_1.x2 - pActive_Camera->x, line_1.y2 - pActive_Camera->y, map_layer_line->start->posz + 0.001f, &white, line_request );
- line_request->line_width = 2;
- line_request->render_count = 50;
- // add request
- pRenderer->Add( line_request );
-
- // create request
- line_request = new cLineRequest();
- pVideo->Draw_Line( line_2.x1 - pActive_Camera->x, line_2.y1 - pActive_Camera->y, line_2.x2 - pActive_Camera->x, line_2.y2 - pActive_Camera->y, map_layer_line->start->posz + 0.001f, &black, line_request );
- line_request->line_width = 2;
- line_request->render_count = 50;
- // add request
- pRenderer->Add( line_request );
- }
-
- // check direction line 1
- if( Col_Line( &line_1, &map_line ) )
- {
- cLine_collision col = cLine_collision();
-
- col.line = map_layer_line;
- col.line_number = Get_Array_Num( map_layer_line );
- col.difference = csize;
-
- // found
- return col;
- }
-
- // check direction line 2
- if( Col_Line( &line_2, &map_line ) )
- {
- cLine_collision col = cLine_collision();
-
- col.line = map_layer_line;
- col.line_number = Get_Array_Num( map_layer_line );
- col.difference = -csize;
-
- // found
- return col;
- }
- }
-
- // not found
- return cLine_collision();
- }
-
- // XML element start
- void cLayer :: elementStart( const CEGUI::String &element, const CEGUI::XMLAttributes &attributes )
- {
- // Property of an Element
- if( element == "Property" )
- {
- xml_attributes.add( attributes.getValueAsString( "name" ), attributes.getValueAsString( "value" ) );
- }
- }
-
- // XML element end
- void cLayer :: elementEnd( const CEGUI::String &element )
- {
- if( element != "Property" )
- {
- if( element == "line" )
- {
- handle_line( xml_attributes );
- }
- else if( element == "layer" )
- {
- // ignore
- }
- else if( element.length() )
- {
- printf( "Warning : Overworld Layer Unknown element : %s\n", element.c_str() );
- }
-
- // clear
- xml_attributes = CEGUI::XMLAttributes();
- }
- }
-
- void cLayer :: handle_line( const CEGUI::XMLAttributes &attributes )
- {
- // create
- cLayer_Line *item = new cLayer_Line();
-
- // Start
- item->start->Set_Pos( static_cast<float>(attributes.getValueAsInteger( "X1" )) - 2, static_cast<float>(attributes.getValueAsInteger( "Y1" )) - 2, 1 );
- // End
- item->end->Set_Pos( static_cast<float>(attributes.getValueAsInteger( "X2" )) - 2, static_cast<float>(attributes.getValueAsInteger( "Y2" )) - 2, 1 );
- // origin
- item->origin = attributes.getValueAsInteger( "origin" );
-
- // add
- Add( item );
- }
-