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

📄 character.cpp

📁 奇迹世界 部分源代码奇迹世界 部分源代码奇迹世界 部分源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Character.cpp: implementation of the Character class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Character.h"
#include "FieldServer.h"
#include <3DEngine/3DTerrain/PathExplorer.h>
#include <3DEngine/3DTerrain/3DTerrain.h>
#include <3DEngine/3DTerrain/WorldBase.h>
#include <PublicMath.h>
#include "SinTable.h"
#include "FieldInfo.h"
#include "Field.h"
#include "AITypes.h"
#include "NPC.h"
#include "SummonedNPCs.h"
#include "Party.h"
#include "PartyManager.h"
#include "PartyState.h"
#include "Map.h"
#include "StatusManager.h"
#include "AbilityStatus.h"
#include "SkillInfoParser.h"
#include "SummonManager.h"
#include "SkillList.h"
#include "CharacterFormula.h"
#include <Global.h>
#include "float.h"
#include "AIParamParser.h"
#include "EtcStatus.h"
#include "StatusManager.h"
#include "RecoverStatus.h"
#include "Summoned.h"
#include "MoveStateControl.h"


class AIMessageSender
{
public :
	AIMessageSender(AI_MSG *pMsg, WORD wSize)
		: m_pMsg(pMsg), m_wSize(wSize)
	{
		ASSERT( pMsg != NULL );
		ASSERT( wSize > 0 );
	}

	BOOL		operator () ( Object* pObject )
	{
		Character* pCharacter = dynamic_cast<Character*>(pObject);
		ASSERT( pCharacter != NULL );

		pCharacter->SendAIMessage( m_pMsg, m_wSize );

		return TRUE;
	}

private :
	AI_MSG*		m_pMsg;
	WORD		m_wSize;
};

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////


Character::Character() : 
m_pWorld(NULL)
{
	SetObjectType( CHARACTER_OBJECT );
	// 辨茫扁 按眉 积己
	m_pPathExplorer = (CPathExplorer*)g_pGameServer->m_fnContactTerrain( CT_NEW_PATH_EXPLORER, 0);
	m_pStatusManager = new StatusManager( this );
	m_pSkillList = new SkillList;
	m_pMoveStateControl = new MoveStateControl;
}

Character::~Character()
{
	g_pGameServer->m_fnContactTerrain( CT_DELETE_PATH_EXPLORER, m_pPathExplorer );

	SAFE_DELETE( m_pSkillList );
	SAFE_DELETE( m_pStatusManager );
	SAFE_DELETE( m_pMoveStateControl );
}

BOOL Character::Init()
{
	ZeroMemory(m_iEnemySlot, sizeof(int)*MAX_ENEMYSLOT_NUM);

	m_PartyState.Init();

	// 胶懦包访
	m_iShieldHP = 0;
	m_iShieldMP = 0;
	m_fShieldAbsorbRatio = 0;
	m_sFightingEnergyCount = 0;

	// 荤噶 版氰摹 颊秦
	m_dwDeadExp = 0;

	m_dwSummonerKey = 0;

	SetGameZone( ePRS_NOT_AT_ZONE, NULL, 0 );

	return Object::Init();	
}

VOID Character::Release()
{
	m_Observers.RemoveAll();
	Object::Release();

	m_pSkillList->Release();
	m_pStatusManager->Release();
}

VOID Character::Update( DWORD dwDeltaTick )
{
	Object::Update( dwDeltaTick );
	
	DWORD curTick = GetTickCount();
	m_pStatusManager->Update( curTick );
	m_pSkillList->Update();
}
VOID Character::AddSkill( Skill * pSkill )
{
	m_pSkillList->Add( pSkill );
}
VOID Character::SetField(Field* pField)
{
	Object::SetField( pField );

	if( NULL == pField )
		m_pWorld = NULL;
	else
		m_pWorld = pField->GetFieldInfo()->GetWorldBase();
}


VOID Character::SetPos( WzVector* pwzVec )
{
	if( m_pWorld )
	{
		GetField()->SetActiveRoom();
		m_pWorld->PathExp_Reset( m_pPathExplorer, *pwzVec );	///< 恐 器牢磐肺 逞扁瘤 臼绊 蔼阑 逞扁瘤??
	}
}

VOID Character::GetPos( WzVector * pWzVecOut ) const
{
	*pWzVecOut = m_pPathExplorer->GetPos();
}

WzVector Character::GetRandomPosInAround( INT iDist )
{
	WzVector pos = m_pPathExplorer->GetPos();
	RandomRangeVector( &pos, iDist );
	GetField()->SetActiveRoom();
	if( -1 == GetWorldBase()->x_pPathFinder->GetTileToStand( pos ) )
		return *m_pPathExplorer->GetPosPtr();
	return pos;
}

// 辨茫扁 版肺 汲沥
BOOL Character::SetPath( WzVector *pwvCur, WzVector *pwvDest, int *pTileRoute, int iNumTileRoute )
{
	// 泅犁 谅钎啊 蜡瓤茄瘤 眉农
	if( !_finite(pwvCur->x) || !_finite(pwvCur->y) || !_finite(pwvCur->z) )
	{
		SUNLOG( eCRITICAL_LOG,  "[Character::SetPath] CurPos is Invalid! x[%f] y[%f] z[%f]", pwvCur->x, pwvCur->y, pwvCur->z );
		return FALSE;
	}

	// 格利瘤 谅钎啊 蜡瓤茄瘤 眉农
	if( !_finite(pwvDest->x) || !_finite(pwvDest->y) || !_finite(pwvDest->z) )
	{
		SUNLOG( eCRITICAL_LOG,  "[Character::SetPath] DestPos is Invalid! x[%f] y[%f] z[%f]", pwvDest->x, pwvDest->y, pwvDest->z );
		return FALSE;
	}

	SetPos( pwvCur );

	if ( iNumTileRoute <= 0 || !pTileRoute || !pwvDest || !m_pPathExplorer )
	{
		SUNLOG( eCRITICAL_LOG,  "[Character::SetPath] PathExp_SetPath 惑狼 颇扼固磐 捞惑 " );
		return FALSE;
	}

	for( int i = 0; i < iNumTileRoute; ++i )
	{
		if( pTileRoute[i] < 0 )
		{
			SUNLOG( eCRITICAL_LOG,  "[Character::SetPath] : iTile of pTileRoute < 0 " );
			return FALSE;
		}
	}

	GetField()->SetActiveRoom();
	if( !m_pWorld->PathExp_SetPath( m_pPathExplorer, pwvDest, pTileRoute, iNumTileRoute ) )
	{
		return FALSE;
	}

	return TRUE;
}

// 辨茫扁 荐青
BOOL Character::PathProgress( float fMove)
{
	Field *pField = GetField();
	if( !pField )
	{
		SUNLOG( eCRITICAL_LOG, "[PathProgress] Field is NULL" );
		return FALSE;
	}

	pField->SetActiveRoom();
	BOOL bRet = m_pWorld->PathExp_Progress( m_pPathExplorer, fMove );
	
	return bRet;	//fMove = 芭府 = 矫埃 * 加档
}

VOID Character::StopMoving()
{
	m_pPathExplorer->Stop();
}

BOOL Character::IsMoving()
{
	return m_pPathExplorer->IsMoving();
}

/*
BOOL Character::CheckMapVersion(DWORD dwCheckSum)	// C/S 甘滚傈捞 老摹窍绰瘤 八荤
{
	if( m_pWorld->GetCheckSum() != dwCheckSum )
	{
		return FALSE;
	}
	else
	{
		if( 0 == dwCheckSum)
		{
			// 0牢 版快绰 备滚傈 甘!!
			return FALSE;
		}
		return TRUE;
	}
}
*/

DWORD Character::IncreaseHP( DWORD dwIncreament )
{
	DWORD hp = min( GetMaxHP(), int(GetHP() + dwIncreament) );
	SetHP( hp );

	m_pStatusManager->ChangeHP();

	return dwIncreament;
}

DWORD Character::DecreaseHP( DWORD dwDecrement )
{
	DWORD curHP = GetHP();

	if (curHP == 0)
	{
		return 0;
	}

	// 蒋靛俊 狼秦 规绢登绰 HP 荐摹甫 备茄促.
	ApplyMagicShield( dwDecrement );

	if( curHP <= dwDecrement )	// 巢篮 HP焊促 歹 腹捞 临绢甸搁 磷绰芭促~
	{
		// 公利惑怕捞搁 磷瘤 臼绰促.
		if( IsStatus(eCHAR_STATE_ETC_UNDEAD) )
		{
			return 0;
		}
		else
		{
			SetHP( 0 );
			OnDead();
		}
	}
	else
	{
		DWORD hp = curHP - dwDecrement;
		SetHP( hp );
	}

	m_pStatusManager->ChangeHP();

	return dwDecrement;
}

DWORD Character::IncreaseMP( DWORD dwIncreament )
{
	DWORD mp = min( GetMaxMP(), int(GetMP() + dwIncreament) );
	SetMP( mp );

	return dwIncreament;
}

DWORD Character::DecreaseMP( DWORD dwDecrement )
{
	DWORD curMP = GetMP();
	if (curMP <= dwDecrement)
	{
		SetMP( 0 );		
	}
	else
	{
		DWORD mp = curMP - dwDecrement;
		SetMP( mp );
	}

	return dwDecrement;
}

VOID Character::ApplyMagicShield( DWORD &dwDecreaseHP )
{
	if( !m_iShieldMP || !m_iShieldHP )		return;

	// MP啊 何练窍搁 蒋靛啊 利侩 救等促.
	if( (int)GetMP() < m_iShieldMP )		return;

	int iShieldDecrement = min( (int)( dwDecreaseHP * m_fShieldAbsorbRatio ), m_iShieldHP );
	dwDecreaseHP = dwDecreaseHP > (DWORD)iShieldDecrement ? ( dwDecreaseHP - iShieldDecrement ) : 0;

	// 蒋靛HP甫 临捞绊 MP甫 皑家矫挪促.
	m_iShieldHP = max( 0, m_iShieldHP - iShieldDecrement );
	SetMP( GetMP() - m_iShieldMP );

	// 蒋靛HP啊 0捞 登搁 概流蒋靛 惑怕甫 秦力茄促.
	if( m_iShieldHP )	return;

	m_pStatusManager->Remove( eCHAR_STATE_MAGIC_SHIELD );
}

int Character::AllocEnemySlot(WzVector *pwvEnemyPos, WzVector &wvResultPos, float fAreaRadius)
{
	// pwzVec甫 扁霖栏肺 啊厘 辟立茄 InitSlot甫 备秦霖促.
	WzVector vCurPos = m_pPathExplorer->GetPos();
	WzVector diffVec = *pwvEnemyPos - vCurPos;
	int CurAngle = Math_GetAngleFromVector2(&diffVec);
	int UnitAngle = 360 / MAX_ENEMYSLOT_NUM;
	int InitSlot = (int)(CurAngle / UnitAngle);
	int MidAngle = (int)(UnitAngle * (InitSlot + 0.5f));

	// InitSlot阑 扁霖栏肺 啊厘 厚绢乐绰 Position阑 且寸秦霖促.
	int MinEnemy = m_iEnemySlot[InitSlot];
	int MinSlot, NextSlot, PrevSlot;
	MinSlot = NextSlot = PrevSlot = InitSlot;

	for(int i = 0; i < MAX_ENEMYSLOT_NUM/4; i++)
	{
		if(CurAngle > MidAngle)
		{
			if(++NextSlot >= MAX_ENEMYSLOT_NUM)	NextSlot -= MAX_ENEMYSLOT_NUM;
			if(--PrevSlot < 0)					PrevSlot += MAX_ENEMYSLOT_NUM;
		}
		else
		{
			if(--NextSlot < 0)					NextSlot += MAX_ENEMYSLOT_NUM;
			if(++PrevSlot >= MAX_ENEMYSLOT_NUM)	PrevSlot -= MAX_ENEMYSLOT_NUM;
		}

		if(MinEnemy > m_iEnemySlot[NextSlot])	
		{
			MinSlot = NextSlot;
			MinEnemy = m_iEnemySlot[MinSlot];
		}
		if(MinEnemy > m_iEnemySlot[PrevSlot])	
		{
			MinSlot = PrevSlot;
			MinEnemy = m_iEnemySlot[MinSlot];
		}
	}

	// 荤侩窍霸 瞪 MinSlot狼 m_iEnemySlot甫 窍唱 疵妨霖促.
	++m_iEnemySlot[MinSlot];

	// 弥辆利栏肺 Enemy(阁胶磐)啊 卵酒具且 谅钎甫 悸泼秦霖促.
	WzVector vRelativePos;
	SetVector(&vRelativePos, FCOS(UnitAngle*MinSlot), FSIN(UnitAngle*MinSlot), 0);
	wvResultPos = vCurPos + vRelativePos*fAreaRadius;

	WzVector diffEnemyVec = wvResultPos - *pwvEnemyPos;
	float fMoveLength2 = Math_Vector2DLength2( &diffEnemyVec );
	if( fMoveLength2 < fAreaRadius * 0.2f * fAreaRadius * 0.2f )
		wvResultPos = vCurPos;

	return MinSlot;
}

VOID Character::FreeEnemySlot(int iSlot)
{
	if(iSlot == -1)		return;

	if(m_iEnemySlot[iSlot] <= 0)	
		return;

	--m_iEnemySlot[iSlot];
}


VOID						
Character::AddObserver(Character* pCharacter)				
{ 
	m_Observers.Add(pCharacter); 
}

VOID						
Character::RemoveObserver(DWORD dwObjKey)		
{ 
	m_Observers.Remove(dwObjKey); 
}

VOID
Character::SendToObservers( AI_MSG *pMsg, WORD wSize )
{
	AIMessageSender op( pMsg, wSize );

	m_Observers.Foreach( op );


	/*
	//////////////////////////////////////////////////////////////////////////	
	if( GetObjectType() == PLAYER_OBJECT &&	pMsg->dwMsgID == AI_MSG_ID_LEAVE_FIELD )
	{
		FILE *fp = fopen( "ObserverListOnLeaveField.txt", "at" );

		fprintf( fp, "Player(%d) ", GetObjectKey() );
		M_OBJECT_LIST_ITR it;
		for( it = m_Observers.begin(); it != m_Observers.end(); ++it )
		{			
			fprintf( fp, "%d ", it->first );			
		}
		fprintf( fp, "" );

		fclose( fp );
	}
	//////////////////////////////////////////////////////////////////////////
	*/
}

VOID Character::OnEnterField(Field* pField, WzVector* pwzVec)
{
	GetStatusManager()->SetCondition( eCHAR_CONDITION_STANDUP );

	Object::OnEnterField(pField, pwzVec);
}

VOID Character::OnLeaveField()
{
	ASSERT( GetObjectKey() != 0 );

	// 磊脚阑 器窃茄 牢立冀磐狼 NPC甸俊霸 pObject啊 鞘靛甫 栋车澜阑 舅妨霖促.
	AI_MSG_LEAVE_FIELD AILeaveMsg;
	AILeaveMsg.dwObjectKey = GetObjectKey();
	SendToObservers( &AILeaveMsg, sizeof(AI_MSG_LEAVE_FIELD) );

	// 家券沥焊俊辑 哗霖促.
	SummonManager::Instance()->LeaveSummonNPCs( this );

	Object::OnLeaveField();
}

BOOL Character::OnDead()
{
	//m_Observers.RemoveAll();
	
	StopMoving();

	// 磷栏搁 葛电 Status甫 波拎具且鳖? --> 绊刮阑 秦焊磊. ;;

	// 磷栏搁 菩澄萍甫 利侩茄促.
	ApplyPenalty();

	return TRUE;
}

BOOL Character::OnResurrection( float fRecoverExp, float fRecoverHP, float fRecoverMP )
{
	if( IsAlive() )	return FALSE;

	// 颊秦夯 版氰摹 雀汗
	DWORD dwRecoverExp = (DWORD)( m_dwDeadExp * fRecoverExp );
	AddExp( dwRecoverExp );

	// HP, MP 雀汗
	DWORD dwRecoverHP = (DWORD)( GetMaxHP() * fRecoverHP );

⌨️ 快捷键说明

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