Code Search for Developers
 
 
  

QuestImporter.cpp from palisma2d at Krugle


Show QuestImporter.cpp syntax highlighted

/**
**************************************************************************************
*Palisma - Secrets of the Illuminati is an open-source 2D RPG                        *
*Copyright (C) 2006, Tony Sparks                                                     *
*                                                                                    *
*This library is free software; you can redistribute it and/or                       *
*modify it under the terms of the GNU Lesser General Public                          *
*License as published by the Free Software Foundation; either                        *
*version 2.1 of the License, or (at your option) any later version.                  *
*                                                                                    *
*This library is distributed in the hope that it will be useful,                     *
*but WITHOUT ANY WARRANTY; without even the implied warranty of                      *
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU                   *
*Lesser General Public License for more details.                                     *
*                                                                                    *
*You should have received a copy of the GNU Lesser General Public                    *
*License along with this library; if not, write to the Free Software                 *
*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA      *
**************************************************************************************
*/
#include "StdAfx.h"
#include "QuestImporter.h"
#include "../shared/StringUtil.h"
#include "../shared/geom.h"
#include "../shared/vector.h"
#include "../render/ViewManager.h"
#include "../render/EntityView.h"
#include "EntityManager.h"
#include "Tile.h"
#include "StateFactory.h"


#include "../kernel.h"

extern Kernel* g_kernel;


QuestImporter::QuestImporter()
{ 
    
}


/** Create the a scene from a .MAP file */
Scene* QuestImporter::CreateScene(const std::string &file)
{
    StringUtil util(file, '.');
    // get the name of the map
    if ( util.HasNext() )
        m_name = util.GetNext();

    Release();

    // parse out the define file
    ParseDefine();

    // allocate memory for the new scene
    Scene* scene = new Scene;

    // parse the layers
    ParseLayers( 1, scene->GetBackgroundLayer(), scene );
    ParseLayers( 2, scene->GetForegroundLayer(), scene );

    // TEMP --HACK-- register the current scene with
    // the entity manager, has to be a better way
    EntityManager::GetInstance()->SetScene( scene );
    // now create the entities
    ParseEntities();

    // Now fill the tiles with events
    ParseEvents( scene );

	return scene;
}

/** Parse the .DFN file */
void QuestImporter::ParseDefine()
{
    std::string sfile = m_name + ".dfn";

    MFile file;
    // open stream
    if ( /*file.Open( sfile ) ) //*/file.OpenZippedFile( sfile ) )
    {
        g_kernel->GetConsole()->Print( ("ERROR: Could not find: " + sfile).c_str() );
        return;
    }
    
	// get the version
	m_version = file.ReadLine();

    // state the version
    g_kernel->GetConsole()->Print( ("--Map version: "+ m_version).c_str() );

    // read the file
    while ( !file.IsEnd() )
    {
        // Read the Char association
        std::string type = file.ReadNext( ":" );
        // read the image file name
        std::string filename = file.ReadNext( ":" );
        // read the frame time
        double frameTime = file.ReadDouble();
        // read the row in the image file
        int row = file.ReadInt();
        // read the col in the image file
        int col = file.ReadInt();

        //std::cout << "Type: " << type << " filename: " << filename << " row: " << row << "\n";
        //
        //  TODO - add animation to tiles
        //
        // load the image
        Image* image = g_kernel->GetResource()->LoadImages( filename, row ,col );
        
        // create the tile
        Tile* tile = new Tile( image, row, col );

        // insert into the map
        m_tiles[ type ] = tile;
    }
    // close off the stream
    file.Close();

}


/** Parse .LY1 and .LY2 files -- The map layer */
void QuestImporter::ParseLayers(int layer, type_Layer &layers, Scene* scene )
{
    std::string sfile =  m_name + ((layer == 1) ? ".ly1" : ".ly2"); 
    MFile file;

    // open stream
    if ( /*file.Open( sfile ) ) //*/file.OpenZippedFile( sfile ) )
    {
        g_kernel->GetConsole()->Print( ("ERROR: Could not find: "+ sfile).c_str() );
        return;
    }

    if ( layer == 1 )
    {
        std::string sound = file.ReadLine();
        g_kernel->GetConsole()->Print( ("--Map loading sound resource: " + sound).c_str() );
        g_kernel->GetSound()->PlayMusic( sound );
    }
    // parse the layer
    Parse( layers, file, scene );

    file.Close();
}


/** Parse a layer file */
void QuestImporter::Parse( type_Layer &layer, MFile &file, Scene* scene  )
{
    // get the map dimensions
    int size_x = file.ReadInt();
    int size_y = file.ReadInt();

    scene->SetMaxX( size_x );
    scene->SetMaxY( size_y );

    // print dimensions
    g_kernel->GetConsole()->Print("--Map dimensions %5d by %5d", size_x, size_y);

    //file.ReadLine();
    for ( int y = 0; y < size_y; y++ ) {
        std::vector<Tile*> subArray;
        for(int x = 0; x < size_x; x++ )
        {
            // read the next tile ref
            std::string next = file.ReadNext(":");
            Tile* tile = NULL;

            // check to see if it is valid
            if ( m_tiles.find( next ) != m_tiles.end() )
                tile = m_tiles[ next ];
            else if ( next == "0" )
            {
                subArray.push_back( NULL );
                continue;
            }
            else {
                // if its not valid, spit out an error message
                g_kernel->GetConsole()->Print( ("**Layer Parsing Error in: "+ file.FileName()).c_str() ); 
                g_kernel->GetConsole()->Print("**On line: %4d %4d", x, y );
                //std::cout << "x: " << x << " y: " << y << " next: " << next << "\n";
                //continue;
                return;
            }
            
            MPoint p(x, y);
            // add the point to the tile
            tile->AddEvent( p, NULL );
        
            // add it to the layer
            subArray.push_back(tile);
                
        }
        file.ReadLine();
        //file.ReadNext("\n");
        layer.push_back( subArray );
        subArray.clear();
    }
    file.Close();
}

/** Parse .EVT file -- The events on each tile */
void QuestImporter::ParseEvents(Scene* scene)
{
    std::string sfile = m_name + ".evt";

    MFile file;
    // open stream
    if ( /*file.Open( sfile ) ) //*/file.OpenZippedFile( sfile ) )
    {
        g_kernel->GetConsole()->Print( ("ERROR: Could not find: "+ sfile).c_str() );
        return;
    }

    while( !file.IsEnd() )
    {
        // the location of the tile
        int tile_x = file.ReadInt();
        int tile_y = file.ReadInt();

        // read the event type
        //int event_type = file.ReadInt();

        /*--------------------------------
            Build the Event structure
        ---------------------------------*/

        // the location of the effected entity
        int location_x = file.ReadInt();
        int location_y = file.ReadInt();

        // get the destination point
        int point_x = file.ReadInt();
        int point_y = file.ReadInt();

        
        // get the damage
        int damage = file.ReadInt();
     
        g_kernel->GetConsole()->Print( "%4d %4d : %4d %4d : %4d %4d : %4d ", tile_x, tile_y, //event_type,
                                        location_x, location_y, point_x,point_y, damage );
        // now find the tile
        Tile* tile = scene->GetTile(1, tile_x, tile_y );

        // Set the destination
        int wx = 0; int wy = 0;
        scene->TileToWorld( point_x, point_y, wx, wy );

        Vector2f dest(wx, wy);
        MPoint tile_location( tile_x, tile_y );

        // create the entity
        MEvent* e = new MEvent;
        e->destination   = dest;
        e->damage        = damage;
        e->type          = 0;          //event_type;
        e->effects       = NULL;     // TODO: Get an entity by point

        // add the event to the tile
        tile->AddEvent( tile_location, e );

    }

    file.Close();
}

/** Parse .ENTS file -- The Entities on a map */
void QuestImporter::ParseEntities()
{
    std::string sfile =  m_name + ".ents";

    MFile file;
    // open stream
    if ( file.OpenZippedFile( sfile ) )
    {
        g_kernel->GetConsole()->Print( ("ERROR: Could not find: "+ sfile).c_str() );
        return;
    }
    g_kernel->GetConsole()->Print( "---Parsing Entities..." );
    // for creating the entity
    EntityManager* entMng = EntityManager::GetInstance();
    // for creating the view of the entity
    ViewManager* vMng = ViewManager::GetInstance();

    while( !file.IsEnd() ) {
        // read the entities type name
        std::string entName = file.ReadNext(":");
        
        IEntity* ent = NULL;
        if ( entName == "player" ) {
            ent = entMng->CreatePlayer( entName );
        } else if ( entName.compare("weapon")==0 ) {
            ent = entMng->CreateWeapon( entName );
        } else
            ent = entMng->CreateEntity( entName );

        ent->SetName( entName );
        ent->m_attributes.Put( "entity_type", entName );

        // read the entities reference
        std::string entRef  = file.ReadNext(":");
        
        /*--------------------------------------------------
            Start reading properties
        ---------------------------------------------------*/

        //
        file.ReadNext("{");
        file.ReadLine();

        bool rightBrace = false;
        while( !file.IsEnd() )
        {
            std::string line = file.ReadLine();

            if ( line == "}" ) 
            {
                rightBrace = true;
                break;
            }
            StringUtil util( line, ':' );
            
            std::string propName, v1, v2;
            // get the name
            if ( util.HasNext() )
            {
                propName = util.GetNext();
            }
            // get the value
            if ( util.HasNext() )
            {
                v1 = util.GetNext();
            }
            // get the 2nd value if applicable
            if ( util.HasNext() )
            {
                v2 = util.GetNext();
            }

            if ( v2 != "" && util.IsNumber( v1) && util.IsNumber( v2 ) )
            {
                ent->m_attributes.Put( propName, util.ToFloat( v1 ), util.ToFloat( v2 )  );     // vector 
            } else if ( util.IsNumber( v1 ) ){
                ent->m_attributes.Put( propName, util.ToInt( v1 ) ); // integer
            } else {
                ent->m_attributes.Put( propName, v1 );   // string
            }
        }

        if ( !rightBrace )
        {
            g_kernel->GetConsole()->Print( ("**Error parsing Entities in: " + sfile + " missing a closing \'}\' ").c_str() );
            g_kernel->GetConsole()->Print( "**On byte: %d of %d", file.GetPosition(), file.Size() );
            delete ent;
            return;
        }

        // apply common attributes
        ent->Apply();

        /*--------------------------------------------------------
            Now parse out the states of these entity
        ---------------------------------------------------------*/
        
        // create the view
        EntityView* view = vMng->CreateView( ent );
        view->SetVisible( true );

        file.ReadNext("{");
        file.ReadLine();
        std::string simage = file.ReadNext(":");
        
        int row = file.ReadInt();
        int col = file.ReadInt();

        Image* image = g_kernel->GetResource()->LoadImages( simage, row, col );
        view->GetModel()->SetImage( image );

        bool rightBrace2 = false;
        // read states
        while( !file.IsEnd() )
        {
            if ( file.Peek() == '}' )
            {
                rightBrace2 = true;
                break;
            }
            // create our model directions
            ModelDirections* dirs = new ModelDirections;

            std::string state   = file.ReadNext(":");
            std::string sound   = file.ReadNext(":");
            std::string script  = file.ReadNext(":");

            // get all four directions
            int animTime = 0;
            for ( int i = 0; i < 4; i++ )
            {
                animTime            = file.ReadInt();
                int imageRow        = file.ReadInt();
                int imageCol        = file.ReadInt();
                int amount          = file.ReadInt();
                
                dirs->AddDirection( i, animTime, imageRow, imageCol, amount );
            }

            // add the state to the model
            view->GetModel()->AddState( state, dirs );
            
            // create the state
            State* entState = StateFactory::GetInstance()->CreateState( state );
            if ( sound != "null" && entState )
                entState->m_sound = g_kernel->GetResource()->LoadSound( sound );
            if ( script != "null" && entState )
                entState->m_scriptFile = script;

            entState->m_nextUpdate = animTime;
            ent->AddState( state, entState );
            file.ReadLine();
        }

        if ( !rightBrace2 )
        {
            g_kernel->GetConsole()->Print( ("**Error parsing Entity Models in: " + sfile + " missing a closing \'}\' ").c_str() );
            g_kernel->GetConsole()->Print( "**On byte: %d of %d", file.GetPosition(), file.Size() );
            return;
        }

        ent->SetState( ENT_STATES[IDLE] );
        // now we can add the ent def
        m_entities[entRef] = ent;
        file.ReadLine();
    }

    file.Close();
}


/** Release resources */
void QuestImporter::Release() 
{
    type_Tiles::iterator it = m_tiles.begin();
    for(; it != m_tiles.end();it++)
    {
        if ( it->second )
            delete it->second;
    }
    m_tiles.clear();
    m_entities.clear();
}

QuestImporter::~QuestImporter(void)
{
    Release();
}






See more files for this project here

palisma2d

The University of Wisconsin-Parkside Developers Union first product. More info to come. Code name Palisma.

Project homepage: http://code.google.com/p/palisma2d/
Programming language(s): C,C++
License: gpl2

  DialogModel.cpp
  DialogModel.h
  DialogState.cpp
  DialogState.h
  Enemy.cpp
  Enemy.h
  EntityController.cpp
  EntityController.h
  EntityEvents.cpp
  EntityEvents.h
  EntityFactory.cpp
  EntityFactory.h
  EntityManager.cpp
  EntityManager.h
  EntityStates.cpp
  EntityStates.h
  Event.h
  HUD.cpp
  HUD.h
  IEntity.cpp
  IEntity.h
  IWeapon.cpp
  IWeapon.h
  InGameState.cpp
  InGameState.h
  Inventory.cpp
  Inventory.h
  MissionHolder.cpp
  MissionHolder.h
  Player.cpp
  Player.h
  PlayerConfig.cpp
  PlayerConfig.h
  PlayerController.cpp
  PlayerController.h
  QuestImporter.cpp
  QuestImporter.h
  ReadMe.txt
  Scene.cpp
  Scene.h
  Shotgun.cpp
  Shotgun.h
  State.h
  StateFactory.cpp
  StateFactory.h
  StateMachine.cpp
  StateMachine.h
  Tile.cpp
  Tile.h
  Weather.cpp
  Weather.h
  stdafx.cpp
  stdafx.h