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

📄 statemachinen.cpp

📁 墨香最新私服
💻 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 + -