Code Search for Developers
 
 
  

IEntity.cpp from palisma2d at Krugle


Show IEntity.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 "IEntity.h"
#include "IWeapon.h"
#include <math.h>
#include "../kernel.h"

extern Kernel* g_kernel;

#define TIME g_kernel->GetTime()
#define RUN_SCRIPT( str ) (g_kernel->GetScriptEngine()->RunFile( #str ))

IEntity::IEntity()
{
    m_active    = true; 
    m_remove    = false;
    m_name      = "Entity"; 
    

    m_bounds.y = m_bounds.x = 0; 
    m_bounds.width  = 0;
    m_bounds.height = 0;

    m_actions       = 0;
    m_health        = 0;
    m_flags         = 0;
    m_id            = 0; 
    m_nextUpdate    = 0.0f;
    m_moveTime      = 0.0f;
    m_heightAboveGround = 0.0f;
    m_gravity       = 0.0f;
    m_face          = SOUTH; 
    m_oldFace       = SOUTH;

    m_dest.Set( 0, 0 );   
    m_throwVel.ZeroOut();
    m_forward.ZeroOut();
    m_world.Set( 0, 0 );
    m_velocity.Set(0,0);
    m_baseVelocity.Set( 0,0 );
    m_position.Set( 0,0 );

    m_carriedent  = NULL;
    m_carrier     = NULL;

    m_entCtrl.SetEntity( this );
    m_FSM.SetOwner( this );
}

IEntity::IEntity(const IEntity &ent)
{
    m_active        = ent.m_active; 
    m_remove        = ent.m_remove;;
    m_name          = ent.m_name; 
    
    m_bounds        = ent.m_bounds;
    m_health        = ent.m_health;
    m_flags         = ent.m_flags;
    m_face          = ent.m_face; 
    m_oldFace       = ent.m_oldFace;

    m_dest          .Set( ent.m_dest );   
    m_throwVel      .Set( ent.m_throwVel );
    m_forward       .Set ( ent.m_forward );
    m_world         .Set( ent.m_world );
    m_velocity      .Set( ent.m_velocity );
    m_baseVelocity  .Set( ent.m_baseVelocity );
    m_position      .Set( ent.m_position );

    m_actions       = 0;
    m_id            = 0; 
    m_nextUpdate    = 0.0f;
    m_moveTime      = 0.0f;
    m_heightAboveGround = 0.0f;
    m_gravity       = 0.0f;
    m_carriedent    = NULL;
    m_carrier       = NULL;

    // TODO - copy the dictionary

    m_entCtrl.SetEntity( this );
    m_FSM.SetOwner( this );
}

// TODO - delete states
IEntity:: ~IEntity()
{
    g_kernel->GetConsole()->Print( "***Entity Memory Report: %d  bytes", sizeof( *this ) );
    // Delete all the states
    type_States::iterator it = m_states.begin();
    for( ; it != m_states.end(); it++ )
    {
        if ( it->second )
            delete it->second;
    }
    
}

/** Apply Common Dictionary Attributes */
void IEntity::Apply()
{
    m_world = m_attributes.GetVector2f("location");
    m_baseVelocity = m_attributes.GetVector2f("base_velocity");
    m_bounds.width = m_attributes.GetInt("width");
    m_bounds.height = m_attributes.GetInt("height");
    m_health = m_attributes.GetInt("health");
    m_position.Set( m_world.x, m_world.y );
    SetBounds( m_world.x /*+ m_bounds.width/2*/, m_world.y + m_bounds.height, m_bounds.width,m_bounds.height);
}

/** Update the Position Coordinates */
void IEntity::UpdateScreenCoord( const Vector2f &screenCoords )
{
    // update the screen coords
    m_position.Set( screenCoords );
}

/** Update bounds */
void IEntity::UpdateCollisionBounds( int x, int y )
{
    //if ( GetName() == "pot1" )
    //std::cout << "***Updating bounds\n";
    SetBounds( x/*+(GetBounds().width/2)*/ , y + GetBounds().height, GetBounds().width, GetBounds().height );
}


/*-------------------------------
    TEMP - Test out moving an entity
-------------------------------*/
/** Update the entity */
void IEntity::Update( long dt) 
{ 
    m_nextUpdate = TIME + 10;
    m_FSM.Update();

    // we are in the possession of 
    // someone else or being thrown
    if ( GetState() == ENT_STATES[ THROWN ] || CarriedBy() )
        return;

    CheckFace(m_actions);   // check the direction of the entity

    // The entity is attempting to attack
    if ( m_actions & BUTTON_ATTACK1 )
    {
        if ( CarryingEntity() )
        {
            Throw();
        }
        else
        {
            // TODO - attack based off of weapon
            m_nextUpdate = TIME + 450; // TEMP
            SetState( ENT_STATES[ATTACKING1] );
            
        }
        return;
    }

    // The entity is attempting to 'use'
    if ( m_actions & BUTTON_USE )
    {
        if ( CarryingEntity() )
        {
            Throw();
        }
        else
        {
            // search for an entity in a region -- TODO THIS IS HORRIBLY SLOW!!!
            IEntity* ent = EntityManager::GetInstance()->FindInRegion( GetReachRectangle(), this );
            
            if ( ent && ent != this )
            {  
                if ( ent->m_attributes.Has( "dialog" ) ) 
                {
                    ent->SetFace( (GetFace() + 2) % 4);
                    ent->SetState( ENT_STATES[TALKING] );
                }
                else if ( ent->m_attributes.Has( "liftable" ) ) 
                {
                    if ( !CarryingEntity() )
                    {
                        Carry( ent );
                    }
                }
                
            }
        }
        return;
    }

    // Check for movement
    if ( m_velocity.Length() )
    {
        // switch the state to walking
        if ( CarryingEntity() )
        {
            SetState( ENT_STATES[CARRYING_WALKING] );
        }
        else
        {
            SetState( ENT_STATES[WALKING] );
        }
    } 
    else
    {
        // switch the state to idle
        if ( CarryingEntity() )
        {
            SetState( ENT_STATES[CARRYING] );
        }
        else
        {
            SetState( ENT_STATES[IDLE] );
        }
    }
}

/** Damage this entity */
int IEntity::Damage( int hit )
{
    // Make sure this entity is destructable
    if ( !m_attributes.Has("health") )
        return 0;

    SetState( ENT_STATES[HIT] );      // set to the hit state
    m_nextUpdate        = TIME + 450; // let the hit animation time run
    int old             = m_health;   // save old health
    m_health           += hit;        // damage the health
    
    // if we are holding something, throw it
    if ( CarryingEntity() )
    {
        Throw();
    }

    // set the dead state
    if ( m_health <= 0 ) 
    {
        // TODO - SET DEAD STATE
        SetState(ENT_STATES[DEAD]);

    }
    return old;
}

/** Throws the entity */
void IEntity::Throw()
{
    
    if ( m_carriedent )
    {
        SetState( ENT_STATES[THROWING] );
        m_carriedent->SetState( ENT_STATES[THROWN] );

        Vector2f thrownTo;

        const float dest = 2.0f;
        thrownTo = m_forward * dest;

        m_carriedent->m_heightAboveGround = 16;
        m_carriedent->MoveToOverTime( thrownTo, TIME + 500 );

        m_carriedent->m_carrier = NULL;
        m_carriedent = NULL;

        //m_nextUpdate = TIME + 600;
    }

}


/** Pick Up an Item */
void IEntity::PickUpItem(IEntity* ent)
{
    ent->m_flags &= ~EF_WP_ONGROUND; // turn off the on ground flag
    ent->m_flags |= EF_NOTONSCREEN;  // don't draw it either
    EntityManager::GetInstance()->RemoveWithoutDeleting( ent );

    // run a picked up script if needed
    if ( ent->m_attributes.Has( "pickedup" ) )
        RUN_SCRIPT( ent->m_attributes.GetStr( "pickedup" ) );

    switch( ent->GetType() )
    {
    case TYPE_BASE:
        m_itemInventory.Add( ent );
        break;
    case TYPE_WEAPON:
        IWeapon* weapon = static_cast<IWeapon*>(ent);
        weapon->SetOwner( this );

        m_weaponInventory.Add( weapon );
        break;
    }
}


/** Arrived to location */
bool IEntity::ArrivedToLocation() 
{ 
    return TIME > m_moveTime; 
} 


/** Get the Reach rectangle - creates a rect infront of entity */
Rect IEntity::GetReachRectangle()
{

    // distance to move 
    int     destw   = GetBounds().width;
    int     desth   = GetBounds().height;
    int     w       = GetBounds().width;
    int     h       = GetBounds().height;

    Vector2f spot; 
    spot.Set( m_world );
    
    switch( GetFace() )
    {
    case NORTH:
        break;
    case EAST:  spot.y += desth; spot.x += destw; 
        break;
    case SOUTH: spot.y += (desth*2);
        break;
    case WEST:  spot.y += desth; spot.x -= destw;
        break;
    }
 
    Rect reach( spot.x, spot.y, w, h );
    return reach;
}

/** Check the face Direction of the player */
void IEntity::CheckFace(int action)
{
    m_velocity.ZeroOut();
 
    int lastFace = GetFace(); 

    // vertical movement
    if( action & BUTTON_UP ) {
        m_velocity.y = -1;
        if( lastFace == SOUTH || !(action & (BUTTON_LEFT|BUTTON_RIGHT)) ) {
            SetFace(NORTH);
        }


    } else if ( action & BUTTON_DOWN ) {
        m_velocity.y = 1;
        if( lastFace == NORTH || !(action & (BUTTON_LEFT|BUTTON_RIGHT)) ) {
            SetFace(SOUTH);
        }
    }

    // horizontal movement
    if( action & BUTTON_LEFT ) {
        m_velocity.x = -1;
        if( lastFace == EAST || !(action & (BUTTON_UP|BUTTON_DOWN)) ) {
            SetFace(WEST);
        } 
    } else if ( action & BUTTON_RIGHT ) {
        m_velocity.x = 1;
        if( lastFace == WEST || !(action & (BUTTON_UP|BUTTON_DOWN)) ) {
            SetFace(EAST);
        }
    }

}


/** Set the direction */
void IEntity::SetFace( int f)
{ 
    m_oldFace   = m_face; 
    m_face      = f; 

    m_forward.ZeroOut();

    // make the correct forward vec
    switch( m_face )
    {
    case NORTH: m_forward.Set( 0, -1 );
        break;
    case SOUTH: m_forward.Set( 0, 1 );
        break;
    case EAST:  m_forward.Set( 1, 0 ); 
        break;
    case WEST:  m_forward.Set( -1, 0 );
        break;
    default:    m_forward.Set( 1, 1 );
        break;
    };
}



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