?? character.cpp
字號:
// 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 + -