📄 statemachinen.cpp
字号:
// StateMachinen.cpp: implementation of the CStateMachinen class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "StateMachinen.h"
#include "MsgRouter.h"
#include "AIParam.h"
#include "Monster.h"
#include "CharMove.h"
#include "AISystem.h"
#include "PackedData.h"
#include "SkillInfo.h"
#include "SkillManager_server.h"
#include "BossMonsterManager.h"
#include "RecallManager.h"
#include "AIGroupManager.h"
#include "RegenPrototype.h"
#include "Player.h"
#include "AIManager.h"
#include "HelpRequestManager.h"
#include "TileManager.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CStateMachinen GSTATEMACHINE;
CStateMachinen::CStateMachinen()
{
}
CStateMachinen::~CStateMachinen()
{
}
void CStateMachinen::RecvMsg( CObject * pSrcObject, CObject * pDestObject, MSG_OBJECT * msg)
{
CStateParam * srcPr = &((CMonster*)pSrcObject)->m_stateParam;
CStateParam * destPr = &((CMonster*)pDestObject)->m_stateParam;
BEGIN_COMMON_MSG(msg->msgID)
MSGOF(eMK_HelpShout)
{
((CMonster *)pDestObject)->AddChat("Help!");
}
MSGOF(eMK_Recall_Script)
{
RECALLINFO * pRecallInfo = ((SMONSTER_LIST*)((CMonster *)pDestObject)->GetSMonsterList())->RecallInfoClass.GetRecallInfo(msg->dwData);
RECALLMGR->RecallObject((CMonster*)pSrcObject, pRecallInfo);
}
MSGOF(eMK_HelpObey)
{
CMonster *pTargetMonster = (CMonster *)pDestObject;
if((CPlayer *)((CMonster *)pSrcObject)->GetTObject())
CHelpRequestManager::SetHelperMonster((CMonster *)pDestObject, (CPlayer *)((CMonster *)pSrcObject)->GetTObject());
}
MSGOF(eMK_HelpRequest)
{
CMonster *pTargetMonster = (CMonster *)pDestObject;
if( destPr->stateCur == eMA_STAND || destPr->stateCur == eMA_WALKAROUND )
{
CRegenObject * pORInfo = GROUPMGR->GetRegenObject(pTargetMonster->GetMonsterGroupNum(), pTargetMonster->GetGridID(), pTargetMonster->GetID());
if(pORInfo)
if(pORInfo->IsHearing())
{
VECTOR3 ObjectPos = *CCharMove::GetPosition(pSrcObject);
VECTOR3 TObjectPos = *CCharMove::GetPosition(pDestObject);
DWORD Distance = (DWORD)CalcDistance( &ObjectPos, &TObjectPos );
if(Distance < pORInfo->GetHearingDistance() && ((CMonster *)pSrcObject)->GetTObject())
{
CHelpRequestManager::SetHelperMonster((CMonster *)pDestObject, (CPlayer *)((CMonster *)pSrcObject)->GetTObject());
}
}
}
}
END_COMMON_MSG
}
void CStateMachinen::SetState(CObject * obj, DWORD newState)
{
CStateParam * pr = &((CMonster*)obj)->m_stateParam;
//if( pr->stateCur == newState )
pr->stateNew = newState;
pr->bStateUpdate = TRUE;
if(newState != eMA_STAND || newState != eMA_ATTACK || newState != eMA_REST)
{
MSG_WORD msg;
msg.Category = MP_MOVE;
msg.Protocol = MP_MOVE_MONSTERMOVE_NOTIFY;
msg.dwObjectID = obj->GetID();
msg.wData = (WORD)newState;
PACKEDDATA_OBJ->QuickSend(obj,&msg,sizeof(msg));
}
}
void CStateMachinen::Process(CObject * obj, eStateEvent evt, MSG_OBJECT * msg)
{
CStateParam * pr = &((CMonster*)obj)->m_stateParam;
CMonster * po = (CMonster *)obj;
if( po->GetState() == eObjectState_Die )
{
return;
}
if(pr->bStateUpdate)
{
pr->bStateUpdate = FALSE;
Update( obj, eSEVENT_Leave, NULL );
pr->stateOld = pr->stateCur;
pr->stateCur = pr->stateNew;
pr->stateNew = 0;
Update( obj, eSEVENT_Enter, NULL );
}
Update( obj, evt, msg );
SubProcess( obj, evt, msg );
}
void CStateMachinen::SubProcess( CObject * obj, eStateEvent evt, MSG_OBJECT * msg )
{
CMonster * po = (CMonster *)obj;
CStateParam * pr = &((CMonster*)obj)->m_stateParam;
BASE_MONSTER_LIST * apr = ((CMonster*)obj)->m_pSInfo;
CAIParam * aprm = &((CMonster*)obj)->m_aiParam;
if((apr == 0) || (aprm == 0) || (pr == 0) || (po == 0))
return;
BEGIN_COMMON_MSG(msg->msgID)
MSGOF(eMK_Chat)
MSGOF(eMK_Recall_Script)
//CRespawnObject * respObj = RESPAWNMGR->GetRespawnObject( msg->flag );
//respObj->ForceGenerate();
END_COMMON_MSG
if(po->IsInSpecialState(eSpecialState_Stun))
{
po->DoStand();
return;
}
switch( pr->stateCur )
{
case eMA_STAND:
case eMA_WALKAROUND:
if( apr->bForeAttack && aprm->SearchLastTime + apr->SearchPeriodicTime < gCurTime )
{
aprm->SearchLastTime = gCurTime;
CObject * TObject = po->DoSearch();
if(TObject &&
TObject->GetState() != eObjectState_Die)
{
if(TObject->GetObjectKind() == eObjectKind_Player)
{
CPlayer * pPlayer = (CPlayer *)TObject;
if(!pPlayer->IsVisible())
{
break;
}
}
if( po->GetGridID() != TObject->GetGridID() )
{
// ASSERT(0);
return;
}
SetState( po, eMA_PERSUIT );
po->SetTObject((CPlayer *)TObject);
}
}
// 250 : 面倒矫 Search窍绰 Delay
else if(apr->AttackNum && aprm->CollSearchLastTime + 250 < gCurTime )
{
aprm->CollSearchLastTime = gCurTime;
CObject * TObject = po->OnCollisionObject();
if(TObject && TObject->GetState() != eObjectState_Die )
{
if(TObject->GetObjectKind() == eObjectKind_Player)
{
CPlayer * pPlayer = (CPlayer *)TObject;
if(!pPlayer->IsVisible())
{
break;
}
}
if( po->GetGridID() != TObject->GetGridID() )
{
// ASSERT(0);
return;
}
SetState( po, eMA_PERSUIT );
po->SetTObject((CPlayer *)TObject);
}
}
break;
}
}
void CStateMachinen::Update(CObject * obj, eStateEvent evt, MSG_OBJECT * msg)
{
CMonster * po = (CMonster *)obj;
CStateParam * pr = &((CMonster*)obj)->m_stateParam;
BEGIN_STATE(pr->stateCur)
STATEOF(eMA_STAND)
DoStand( po, evt, msg );
STATEOF(eMA_WALKAROUND)
DoWalkAround( po, evt, msg );
STATEOF(eMA_PERSUIT)
DoPursuit( po, evt, msg );
STATEOF(eMA_RUNAWAY)
DoRunAway( po, evt, msg );
STATEOF(eMA_ATTACK)
DoAttack( po, evt, msg );
STATEOF(eMA_REST)
DoRest( po, evt, msg );
END_STATE
}
void CStateMachinen::DoRest( CObject * pObject, eStateEvent evt, MSG_OBJECT * msg )
{
CMonster * po = (CMonster *)pObject;
CStateParam * pr = &((CMonster*)pObject)->m_stateParam;
BASE_MONSTER_LIST * apr = ((CMonster*)pObject)->m_pSInfo;
BEGIN_EVENT(evt)
OnEnter
OnLeave
OnMsg
/////////////////////////////////////
//////////// NULL /////////////////
/////////////////////////////////////
OnProcess
END_EVENT
}
void CStateMachinen::DoStand( CObject * pObject, eStateEvent evt, MSG_OBJECT * msg )
{
CMonster * po = (CMonster *)pObject;
CStateParam * pr = &((CMonster*)pObject)->m_stateParam;
BASE_MONSTER_LIST * apr = ((CMonster*)pObject)->m_pSInfo;
BEGIN_EVENT(evt)
OnEnter
po->SetTObject(NULL);
pr->stateStartTime = gCurTime;
pr->stateEndTime = pr->stateStartTime + apr->StandTime /*+沥瘤蜡瘤 矫埃*/;
po->DoStand();
OnLeave
/////////////////////////////////////
//////////// NULL /////////////////
/////////////////////////////////////
OnMsg
/////////////////////////////////////
//////////// NULL /////////////////
/////////////////////////////////////
OnProcess
if( pr->stateEndTime < gCurTime )
{
int rate = rand()%100;
if(0 <= rate && rate < apr->StandRate )
{
SetState( po, eMA_STAND );
}
else
{
SetState( po, eMA_WALKAROUND );
}
}
END_EVENT
}
void CStateMachinen::DoWalkAround( CObject * pObject, eStateEvent evt, MSG_OBJECT * msg )
{
CMonster * po = (CMonster *)pObject;
CStateParam * pr = &((CMonster*)pObject)->m_stateParam;
BASE_MONSTER_LIST * apr = ((CMonster*)pObject)->m_pSInfo;
BEGIN_EVENT(evt)
OnEnter
po->SetTObject(NULL);
po->DoWalkAround();
pr->stateStartTime = gCurTime;
pr->stateEndTime = pr->stateStartTime + CCharMove::GetMoveEstimateTime(po);
OnLeave
/////////////////////////////////////
//////////// NULL /////////////////
/////////////////////////////////////
OnMsg
/////////////////////////////////////
//////////// NULL /////////////////
/////////////////////////////////////
OnProcess
if( pr->stateEndTime < gCurTime )
{
int rate = rand()%100;
if(0 <= rate && rate < apr->StandRate )
{
SetState( po, eMA_STAND );
}
else
{
SetState( po, eMA_WALKAROUND );
}
}
END_EVENT
}
void CStateMachinen::DoPursuit( CObject * pObject, eStateEvent evt, MSG_OBJECT * msg )
{
CMonster * po = (CMonster *)pObject;
CStateParam * pr = &((CMonster*)pObject)->m_stateParam;
BASE_MONSTER_LIST * apr = ((CMonster*)pObject)->m_pSInfo;
CAIParam * aprm = &((CMonster*)pObject)->m_aiParam;
// yh 欢唱辑 绊魔(炔釜焊拱捞 眠拜葛靛... -_-)
if(apr->SkillInfo[aprm->GetCurAttackKind()] == NULL)
{
ASSERT(0);
SetState(pObject, eMA_STAND);
return;
}
if( !po->GetTObject() || (po->GetTObject() && ( po->GetTObject()->GetState() == eObjectState_Die || po->GetTObject()->GetInited() == FALSE ) ) )
{
SetState(pObject, eMA_STAND);
return;
}
BEGIN_EVENT(evt)
OnEnter
// apr->PursuitForgiveStartTime = gCurTime;
aprm->PursuitForgiveStartTime = gCurTime;
pr->stateStartTime = 0;
pr->stateEndTime = 1000;
po->DoPursuit();
CAIManager::RandCurAttackKind(apr, aprm);
OnLeave
/////////////////////////////////////
//////////// NULL /////////////////
/////////////////////////////////////
OnMsg
/////////////////////////////////////
//////////// NULL /////////////////
/////////////////////////////////////
OnProcess
VECTOR3 ObjectPos = *CCharMove::GetPosition(po);
VECTOR3 TObjectPos = *CCharMove::GetPosition(po->GetTObject());
DWORD Distance = (DWORD)CalcDistanceXZ( &ObjectPos, &TObjectPos );
// if( aprm->prePursuitForgiveTime == 0 && ( apr->PursuitForgiveStartTime + apr->PursuitForgiveTime < gCurTime || apr->PursuitForgiveDistance < Distance ) )
if( aprm->prePursuitForgiveTime == 0 && ( aprm->PursuitForgiveStartTime + apr->PursuitForgiveTime < gCurTime || apr->PursuitForgiveDistance < Distance ) )
{
aprm->SearchLastTime = gCurTime + 3000; //3檬埃 急傍各 辑摹甫 救窍霸 窍扁 困秦辑.
SetState( po, eMA_WALKAROUND );
}
else
{
// if( aprm->prePursuitForgiveTime != 0 && apr->PursuitForgiveStartTime + aprm->prePursuitForgiveTime < gCurTime )
if( aprm->prePursuitForgiveTime != 0 && aprm->PursuitForgiveStartTime + aprm->prePursuitForgiveTime < gCurTime )
{
aprm->prePursuitForgiveTime = 0;
aprm->SearchLastTime = gCurTime + 3000; //3檬埃 急傍各 辑摹甫 救窍霸 窍扁 困秦辑.
SetState( po, eMA_WALKAROUND );
}
else if( Distance < apr->SkillInfo[aprm->GetCurAttackKind()]->GetSkillRange() )
{
SetState( po, eMA_ATTACK );
//aprm->PursuitForgiveStartTime = gCurTime;
}
else
{
if( pr->stateStartTime + pr->stateEndTime < gCurTime )
{
pr->stateStartTime = gCurTime;
po->DoPursuit();
//眠拜窍搁辑 傍拜菩畔阑 官槽促. //KES 何窍啊 乐栏妨唱?
CAIManager::RandCurAttackKind(apr, aprm);
}
}
}
END_EVENT
}
void CStateMachinen::DoAttack( CObject * pObject, eStateEvent evt, MSG_OBJECT * msg )
{
CMonster * po = (CMonster *)pObject;
CStateParam * pr = &((CMonster*)pObject)->m_stateParam;
BASE_MONSTER_LIST * apr = ((CMonster*)pObject)->m_pSInfo;
CAIParam * aprm = &((CMonster*)pObject)->m_aiParam;
// targetobject啊 NULL牢版快啊 唱咳!!
if( !po->GetTObject() || (po->GetTObject() && ( po->GetTObject()->GetState() == eObjectState_Die || po->GetTObject()->GetInited() == FALSE ) ) )
{
SetState(pObject, eMA_STAND);
return;
}
BEGIN_EVENT(evt)
OnEnter
pr->stateStartTime = gCurTime;
pr->stateEndTime = 0;
OnLeave
/////////////////////////////////////
//////////// NULL /////////////////
/////////////////////////////////////
OnMsg
/////////////////////////////////////
//////////// NULL /////////////////
/////////////////////////////////////
OnProcess
if(aprm->CurAttackKind < apr->AttackNum)
{
if(apr->SkillInfo[aprm->GetCurAttackKind()]->GetDelayTime() + aprm->AttackStartTime < gCurTime)
{
VECTOR3 ObjectPos = *CCharMove::GetPosition(po);
VECTOR3 TObjectPos = *CCharMove::GetPosition(po->GetTObject());
DWORD Distance = (DWORD)CalcDistanceXZ( &ObjectPos, &TObjectPos );
if( Distance > apr->SkillInfo[aprm->GetCurAttackKind()]->GetSkillRange() )
{
SetState(po, eMA_PERSUIT);
}
else
{
aprm->AttackStartTime = gCurTime;
po->DoAttack( (WORD)apr->AttackIndex[aprm->GetCurAttackKind()] );
CAIManager::RandCurAttackKind(apr, aprm);
}
}
}
else
{
SetState(po, eMA_STAND);
}
END_EVENT
}
void CStateMachinen::DoRunAway( CObject * pObject, eStateEvent evt, MSG_OBJECT * msg )
{
CMonster * po = (CMonster *)pObject;
CStateParam * pr = &((CMonster*)pObject)->m_stateParam;
BASE_MONSTER_LIST * apr = ((CMonster*)pObject)->m_pSInfo;
CAIParam * aprm = &((CMonster*)pObject)->m_aiParam;
BEGIN_EVENT(evt)
OnEnter
po->SetTObject(NULL);
po->DoRunaway();
pr->stateStartTime = gCurTime;
pr->stateMidTime = 1000;
pr->stateEndTime = pr->stateStartTime + CCharMove::GetMoveEstimateTime(po) + 1000;
OnLeave
OnMsg
OnProcess
if( pr->stateEndTime < gCurTime )
{
switch(aprm->RunawayType)
{
case eRunawayType_Help:
{
ASSERT(aprm->pTarget);
po->SetTObject(aprm->pTarget);
aprm->pHelperMonster->m_aiParam.prePursuitForgiveTime = 20000;
aprm->prePursuitForgiveTime = 20000;
SetState(po, eMA_PERSUIT);
CHelpRequestManager::SetHelperMonster(aprm->pHelperMonster, aprm->pTarget);
//ASSERT(po != aprm->pHelperMonster);
//CMonster * pHelper = (CMonster *)g_pUserTable->FindUser(aprm->pHelperMonster->GetID());
//if(!pSrcObj) return;
}
break;
case eRunawayType_General:
{
int rate = rand()%100;
if(0 <= rate && rate < apr->StandRate )
{
SetState( po, eMA_STAND );
}
else
{
SetState( po, eMA_WALKAROUND );
}
}
break;
}
aprm->RunawayType = eRunawayType_Terminate;
}
else
{
if(pr->stateStartTime + pr->stateMidTime < gCurTime)
{
pr->stateMidTime += 1000;
switch(aprm->RunawayType)
{
case eRunawayType_Help:
{
po->DoPursuit(aprm->pHelperMonster);
}
break;
}
}
}
END_EVENT
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -