⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 player.cpp

📁 MUD游戏编程光盘代码
💻 CPP
字号:
// MUD Programming
// Ron Penton
// (C)2003
// Player.cpp - The class defining Players in the SimpleMUD
// 
// 

#include <cmath>
#include <string>
#include <fstream>
#include <vector>

#include "SimpleMUDLogs.h"
#include "Player.h"
#include "Item.h"

namespace SimpleMUD
{



Player::Player()
{
    m_pass = "UNDEFINED";
    m_rank = REGULAR;

    m_connection = 0;
    m_loggedin = false;
    m_active = false;
    m_newbie = true;

    m_experience = 0;
    m_level = 1;
    m_room = 1;
    m_money = 0;

    m_nextattacktime = 0;

    m_baseattributes[STRENGTH] = 1;
    m_baseattributes[HEALTH]   = 1;
    m_baseattributes[AGILITY]  = 1;

    m_items = 0;
    m_weapon = -1;
    m_armor = -1;

    m_statpoints = 18;

    RecalculateStats();
    m_hitpoints = GetAttr( MAXHITPOINTS );
}


int Player::NeedForNextLevel()
{
    // how much more experience to the next level
    return NeedForLevel( m_level + 1 ) - m_experience;
}


bool Player::Train()
{
    if( NeedForNextLevel() <= 0 )
    {
        m_statpoints += 2;
        m_baseattributes[MAXHITPOINTS] += m_level;
        m_level++;
        RecalculateStats();
        return true;
    }
    else
    {
        return false;
    }
}


void Player::RecalculateStats()
{
    m_attributes[MAXHITPOINTS] = 
        10 + ( (int)(m_level * ( GetAttr( HEALTH ) / 1.5 )) );

    m_attributes[HPREGEN] = 
        ( GetAttr( HEALTH ) / 5 ) + m_level;

    m_attributes[ACCURACY] = GetAttr( AGILITY ) * 3;
    m_attributes[DODGING] = GetAttr( AGILITY ) * 3;
    m_attributes[DAMAGEABSORB] = GetAttr( STRENGTH ) / 5;
    m_attributes[STRIKEDAMAGE] = GetAttr( STRENGTH ) / 5;

    // make sure the hitpoints don't overflow if your max goes down
    if( m_hitpoints > GetAttr( MAXHITPOINTS ) )
        m_hitpoints = GetAttr( MAXHITPOINTS );
 
    if( Weapon() != 0 )
        AddDynamicBonuses( Weapon() );
    if( Armor() != 0 )
        AddDynamicBonuses( Armor() );
}

void Player::AddDynamicBonuses( item p_item )
{
    if( p_item == 0 )
        return;

    Item& i = *p_item;

    for( int x = 0; x < NUMATTRIBUTES; x++ )
        m_attributes[x] += i.GetAttr( x );
}


void Player::SetBaseAttr( int p_attr, int p_val )
{
    m_baseattributes[p_attr] = p_val;
    RecalculateStats();
}


void Player::AddToBaseAttr( int p_attr, int p_val )
{
    m_baseattributes[p_attr] += p_val;
    RecalculateStats();
}

void Player::AddHitpoints( int p_hitpoints )
{
    SetHitpoints( m_hitpoints + p_hitpoints );
}

void Player::SetHitpoints( int p_hitpoints )
{
    m_hitpoints = p_hitpoints;

    if( m_hitpoints < 0 )
        m_hitpoints = 0;
    if( m_hitpoints > GetAttr( MAXHITPOINTS ) )
        m_hitpoints = GetAttr( MAXHITPOINTS );
}


bool Player::PickUpItem( item p_item )
{
    if( m_items < MaxItems() )
    {
        // find the first open index to put the item in.
        item* itr = m_inventory;
        while( *itr != 0 )
            ++itr;

        // insert the item
        *itr = p_item;
        m_items++;

        return true;
    }
    return false;
}


bool Player::DropItem( int p_index )
{
    if( m_inventory[p_index] != 0 )
    {
        // remove the weapon or armor if needed
        if( m_weapon == p_index )
            RemoveWeapon();
        if( m_armor == p_index )
            RemoveArmor();

        m_inventory[p_index] = 0;
        m_items--;

        return true;
    }
    return false;
}

void Player::AddBonuses( item p_item )
{
    if( p_item == 0 )
        return;

    Item& itm = *p_item;
    for( int i = 0; i < NUMATTRIBUTES; i++ )
        m_baseattributes[i] += itm.GetAttr( i );

    RecalculateStats();
}



void Player::RemoveWeapon()
{
    m_weapon = -1;
    RecalculateStats();
}


void Player::RemoveArmor()
{
    m_armor = -1;
    RecalculateStats();
}


void Player::UseWeapon( int p_index )
{
    RemoveWeapon();
    m_weapon = p_index;
    RecalculateStats();
}


void Player::UseArmor( int p_index )
{
    RemoveArmor();
    m_armor = p_index;
    RecalculateStats();
}


// ------------------------------------------------------------------------
//  This gets the index of an item within the players inventory given a 
//  name.
// ------------------------------------------------------------------------
int Player::GetItemIndex( const std::string& p_name )
{
    item* i = double_find_if( m_inventory, 
                              m_inventory + MaxItems(),
                              matchentityfull( p_name ),
                              matchentity( p_name ) );

    if( i == m_inventory + MaxItems() )
        return -1;
    return (int)(i - m_inventory);
}


// ------------------------------------------------------------------------
//  This sends a string to the players connection.
// ------------------------------------------------------------------------
void Player::SendString( const std::string& p_string )
{
    using namespace SocketLib;

    if( Conn() == 0 )
    {
        ERRORLOG.Log( "Trying to send string to player " +
                      Name() + " but player is not connected." );
        return;
    }

    // send the string, newline included.
    Conn()->Protocol().SendString( *Conn(), p_string + newline );

    if( Active() )
    {
        PrintStatbar();
    }
}

// ------------------------------------------------------------------------
//  This prints up the players "statbar", ie: his hitpoints.
// ------------------------------------------------------------------------
void Player::PrintStatbar( bool p_update )
{
    using namespace SocketLib;
    using namespace BasicLib;

    // if this is a statusbar update and the user is currently typing something,
    // then do nothing.
    if( p_update && Conn()->Protocol().Buffered() > 0 )
        return;

    string statbar = white + bold + "[";

    int ratio = 100 * HitPoints() / GetAttr( MAXHITPOINTS );

    // color code your hitpoints so that they are red if low,
    // yellow if medium, and green if high.
    if( ratio < 33 )
        statbar += red;
    else if( ratio < 67 )
        statbar += yellow;
    else 
        statbar += green;

    statbar += tostring( HitPoints() ) + white + "/" + 
                tostring( GetAttr( MAXHITPOINTS ) ) + "] ";

    Conn()->Protocol().SendString( *Conn(), clearline + "\r" + statbar + reset );
}



// --------------------------------------------------------------------
//  Inserts an item in text form into a stream
// --------------------------------------------------------------------
ostream& operator<<( ostream& p_stream, const Player& p )
{
    p_stream << "[NAME]           " << p.m_name << "\n";
    p_stream << "[PASS]           " << p.m_pass << "\n";
    p_stream << "[RANK]           " << GetRankString( p.m_rank ) << "\n";
    p_stream << "[STATPOINTS]     " << p.m_statpoints << "\n";
    p_stream << "[EXPERIENCE]     " << p.m_experience << "\n";
    p_stream << "[LEVEL]          " << p.m_level << "\n";
    p_stream << "[ROOM]           " << p.m_room << "\n";
    p_stream << "[MONEY]          " << p.m_money << "\n";
    p_stream << "[HITPOINTS]      " << p.m_hitpoints << "\n";
    p_stream << "[NEXTATTACKTIME] "; insert( p_stream, p.m_nextattacktime );
    p_stream << "\n";
    p_stream << p.m_baseattributes;

    p_stream << "[INVENTORY]      ";
    for( int i = 0; i < p.MaxItems(); i++ )
    {
        p_stream << p.m_inventory[i] << " ";
    }
    p_stream << "\n";


    p_stream << "[WEAPON]         " << p.m_weapon << "\n";
    p_stream << "[ARMOR]          " << p.m_armor << "\n";

    return p_stream;
}


// --------------------------------------------------------------------
//  Extracts an item in text form from a stream
// --------------------------------------------------------------------
istream& operator>>( istream& p_stream, Player& p )
{
    std::string temp;
    p_stream >> temp >> std::ws;
    std::getline( p_stream, p.m_name );
    p_stream >> temp >> p.m_pass;
    p_stream >> temp >> temp;
    p.m_rank = GetRank( temp );
    p_stream >> temp >> p.m_statpoints;
    p_stream >> temp >> p.m_experience;
    p_stream >> temp >> p.m_level;
    p_stream >> temp >> p.m_room;
    p_stream >> temp >> p.m_money;
    p_stream >> temp >> p.m_hitpoints;
    p_stream >> temp; extract( p_stream, p.m_nextattacktime );
    p_stream >> p.m_baseattributes;

    p_stream >> temp;
    p.m_items = 0;
    for( int i = 0; i < p.MaxItems(); i++ )
    {
        p_stream >> p.m_inventory[i];
        if( p.m_inventory[i] != 0 )   
            p.m_items++;
    }

    p_stream >> temp >> p.m_weapon;
    p_stream >> temp >> p.m_armor;

    p.RecalculateStats();

    return p_stream;
}




}   // end namespace SimpleMUD

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -