📄 pet.cpp
字号:
case _PET_ATTACK:
this->ProcessAI_Attack();
break;
default:
break;
}
this->ProcessAI_GenerateNewBehavior();
}
//--------------------------------------------------------------------------------------
void CPet::ProcessAI_Idle()
{
if(::TimeGet() > m_dwIdleEnd)
m_nBehaviorType = _PET_BEHAVIOR_READY;
}
//--------------------------------------------------------------------------------------
void CPet::ProcessAI_Ready()
{
}
//--------------------------------------------------------------------------------------
void CPet::ProcessAI_Attack()
{
if(this->IsAttacking())
return;
else if(m_idTarget == ID_NONE)
return;
else
{
CPlayer* pPlayer = g_objPlayerSet.GetPlayer(m_idTarget, true);
if(pPlayer && !pPlayer->IsDead())
{
this->LockAttack(pPlayer);
}
else
m_idTarget = ID_NONE;
}
}
//--------------------------------------------------------------------------------------
void CPet::ProcessAI_GenerateNewBehavior()
{
CMyPos posHero, posPet;
g_objHero.GetPos(posHero);
this->GetPos(posPet);
if(m_nBehaviorType == _PET_IDLE)
return;
this->CheckTarget();
/*
if (this->CanMagicAtk())
{
m_nBehaviorType = _PET_MAGICATTACK;
return;
}*/
// else
if(m_idTarget != ID_NONE)
{
m_nBehaviorType = _PET_ATTACK;
return;
}
}
//--------------------------------------------------------------------------------------
void CPet::ProcessAI_FindHost(int nDistance)
{
CMyPos posPet,posNext,posHero;
g_objHero.GetPos(posHero);
this->GetPos(posPet);
this->GetNextPos(posNext.x,posNext.y);
if(posNext.x == 0)
return;
CellInfo* pCellInfo = g_objGameMap.GetCell(posNext.x, posNext.y);
CPath objPath;
g_objGameMap.FindPath(objPath,posPet,posNext);
if(!pCellInfo || g_objGameMap.GetGroundMask(pCellInfo) == 1||(!objPath.GetStepAmount()&&posPet.x != posNext.x && posPet.y != posNext.y))
{
posNext.x = posHero.x + _DELTA_X[::RandGet(8)]*4-::RandGet(2);
posNext.y = posHero.y + _DELTA_Y[::RandGet(8)]*4-::RandGet(2);
g_objGameMap.FindPath(objPath,posPet,posNext);
if(objPath.GetStepAmount())
this->SetNextPos(posNext.x,posNext.y);
}
CPlayer* pPlayer = g_objPlayerSet.GetPlayer(posPet.x, posPet.y);
if(abs(posHero.x - posPet.x) < nDistance && abs(posHero.y - posPet.y) < nDistance && pPlayer== this
&&posPet.x == posNext.x && posPet.y == posNext.y )
{
m_nBehaviorType = _PET_BEHAVIOR_READY;
}
else if(!this->IsAttacking())
{
/*CellInfo* */pCellInfo = g_objGameMap.GetCell(posPet.x, posPet.y);
if(!pCellInfo || g_objGameMap.GetGroundMask(pCellInfo) == 1 )
return;
if (abs(posHero.x - posPet.x) < 8 && abs(posHero.y - posPet.y) < 8)
{
if (this->GetCommandType() == _COMMAND_WALK||this->GetCommandType() == _COMMAND_RUN)
this->AddStep(posNext);
else
{
this->Run(posNext.x, posNext.y);
}
}
else if(!this->IsMoving() )
{
this->Transfer(posNext.x, posNext.y);
}
}
}
//--------------------------------------------------------------------------------------
void CPet::AddPetSoul(int nAmount)
{
OBJID idPetItem = this->GetItemID();
CItem* pItem = g_objHero.GetItem(idPetItem);
if (!pItem)
return;
if (!this->IsGhost())
{
pItem->SetWarGhostExp(pItem->GetMonsterMaxLife());
return;
}
else
{
if (nAmount > 100)
nAmount = 100;
DWORD dwCurLife =pItem->GetWarGhostExp() + pItem->GetMonsterMaxLife()*nAmount/100;
pItem->SetWarGhostExp(dwCurLife);
}
::PostCmd(CMD_FLASH_MYPETINFO);
}
//--------------------------------------------------------------------------------------
void CPet::ReplaceStatus(__int64 dwStatus)
{
// die
if (dwStatus&USERSTATUS_GHOST) //
{
if (this->IsPet() && !this->TestStatus(USERSTATUS_GHOST)) //没有死,是幻兽
{
if (this->GetLook()!=999)
m_AliveLook = this->GetLook();
this->m_objEffect.Add("baby_d3");
this->SetLook(999);
if (this->IsMyPet())
{
this->StandBy();
CItem* pPet = g_objHero.GetItem(this->GetItemID());
if (pPet)
pPet->SetMonsterDie(true);
::PostCmd(CMD_PET_DIE, this->GetID());
}
}
}
else
{
if (this->IsPet() && this->TestStatus(USERSTATUS_GHOST)) //死,是幻兽
{
this->m_objEffect.Add("baby_d10");
this->SetLook(m_AliveLook);
if (this->IsMyPet())
{
this->StandBy();
CItem* pPet = g_objHero.GetItem(this->GetItemID());
if (pPet)
pPet->SetMonsterDie(false);
::PostCmd(CMD_PET_ALIVE,this->GetID());
}
}
}
CPlayer::ReplaceStatus(dwStatus);
}
//--------------------------------------------------------------------------------------
void CPet::LockAttack (CPlayer* pTarget)
{
if (!pTarget)
return;
if (this->IsAttacking())
return;
if (this->IsDead() || pTarget->IsDead())
return;
if(g_objGameMap.GetType() & MAPTYPE_BOOTH_ENABLE)
return;
this->Idle(4000);
// attack now
{
// set lock attck command
CCommand cmd;
cmd.iType =_COMMAND_LOCKATK;
cmd.iStatus =_CMDSTATUS_BEGIN;
cmd.idTarget =pTarget->GetID();
this->SetCommand(&cmd);
m_bFirstAtk = true;
}
}
//--------------------------------------------------------------------------------------
void CPet::Transfer(int nPosX, int nPosY)
{
CMyPos posPet;
posPet.x = nPosX;
posPet.y = nPosY;
CPlayer* pPlayer = g_objPlayerSet.GetPlayer(nPosX, nPosY);
CellInfo* pCellInfo = g_objGameMap.GetCell(nPosX, nPosY);
if(!pCellInfo ||
g_objGameMap.GetGroundMask(pCellInfo) == 1 )
{
return;
}
CMsgAction msg;
if(msg.Create(this->GetID(), posPet.x, posPet.y, m_Info.cmdProc.nDir, actionJump, posPet.x, posPet.y, m_Info.cmdProc.dwData))
msg.Send();
this->SetPos(posPet);
}
//--------------------------------------------------------------------------------------
BOOL CPet::CanJump(CMyPos posTarGet)
{
// Can I Jump Over It?
int nCanJumpHeight = 200;
// if(this->TestStatus(USERSTATUS_FLY))
// nCanJumpHeight = 100;
CMyPos posStart, posEnd;
posEnd = posTarGet;
DEQUE_CELL setCell;
this->GetPos(posStart);
CMyPos posHighest;
g_objGameMap.Sampling(setCell, posHighest, posStart, posEnd, 32);
CellInfo* pTargetCell = g_objGameMap.GetCell(posHighest.x, posHighest.y);
if(!pTargetCell)
return false;
CellInfo* pCellInfo = g_objGameMap.GetCell(posStart.x, posStart.y);
if(!pCellInfo)
return false;
if(g_objGameMap.GetGroundAltitude(pTargetCell) - g_objGameMap.GetGroundAltitude(pCellInfo) > nCanJumpHeight)
return false;
return true;
}
//--------------------------------------------------------------------------------------
void CPet::Walk(int nPosX, int nPosY)
{
int nCommandType = this->GetCommandType();
if(nCommandType == _COMMAND_ATTACK ||
nCommandType == _COMMAND_ACTION ||
nCommandType == _COMMAND_EMOTION ||
nCommandType == _COMMAND_WOUND ||
nCommandType == _COMMAND_DEFEND)
this->ResetActionData();
if(this->GetCommandType() == _COMMAND_ATTACK)
this->ResetActionData();
extern UINT g_uStatus;
if (_STATUS_NORMAL != g_uStatus)
return;
// this->AbortIntone();
if (this->IsDead() && !this->TestStatus(USERSTATUS_GHOST))
return;
// prevent repeat the same target point
CCommand* pcmdNow =this->GetCommand();
if(_COMMAND_WALK == pcmdNow->iType)
{
if(nPosX == pcmdNow->posTarget.x &&
nPosY == pcmdNow->posTarget .y)
return;
}
// set command of role
CCommand cmd;
cmd.iType =_COMMAND_WALK;
cmd.iStatus =_CMDSTATUS_BEGIN;
cmd.posTarget.x =nPosX;
cmd.posTarget.y =nPosY;
this->SetCommand(&cmd);
}
//--------------------------------------------------------------------------------------
void CPet::Run(int nPosX, int nPosY)
{
// if(this->IsMagicLock())
// return;
if(this->TestStatus(USERSTATUS_CANNOTMOVE))
return;
// this->StopChargeUp();
int nCommandType = this->GetCommandType();
if(nCommandType == _COMMAND_ATTACK ||
nCommandType == _COMMAND_ACTION ||
nCommandType == _COMMAND_EMOTION ||
nCommandType == _COMMAND_WOUND ||
nCommandType == _COMMAND_DEFEND)
this->ResetActionData();
// if(this->TestStatus(USERSTATUS_FLY))
// {
// this->Jump(nPosX, nPosY);
// return;
// }
if(this->GetCommandType() == _COMMAND_ATTACK)
this->ResetActionData();
// if(m_objBoothManager.IsActive())
// return;
extern UINT g_uStatus;
if (_STATUS_NORMAL != g_uStatus)
return;
// this->AbortIntone();
/*
if (this->IsDead())
{
if (this->TestStatus(USERSTATUS_GHOST))
this->Walk(nPosX, nPosY);
return;
}*/
// prevent repeat the same target point
CCommand* pcmdNow =this->GetCommand();
if(_COMMAND_RUN == pcmdNow->iType)
{
if(nPosX == pcmdNow->posTarget.x &&
nPosY == pcmdNow->posTarget .y)
return;
}
// here got player already
CPlayer* pPlayer = g_objPlayerSet.GetPlayer(nPosX, nPosY);
if (pPlayer && !pPlayer->IsDead())
return;
// set command of role
CCommand cmd;
cmd.iType =_COMMAND_RUN;
cmd.iStatus =_CMDSTATUS_BEGIN;
cmd.posTarget.x =nPosX;
cmd.posTarget.y =nPosY;
this->SetCommand(&cmd);
}
//--------------------------------------------------------------------------------------
DWORD CPet::SetCommand(CCommand* pCommand)
{
if (!pCommand)
return 0;
m_dwCommandIndex++;
pCommand->dwIndex = m_dwCommandIndex;
// lock attack 命令不可积累
if(pCommand->iType == _COMMAND_LOCKATK ||
pCommand->iType == _COMMAND_WALK ||
pCommand->iType == _COMMAND_RUN)
{
for(int i = 0; i < m_infoPlayer.setCmd.size(); i ++)
{
if(m_infoPlayer.setCmd[i].iType == _COMMAND_LOCKATK ||
pCommand->iType == _COMMAND_WALK ||
pCommand->iType == _COMMAND_RUN)
{
m_infoPlayer.setCmd.erase(m_infoPlayer.setCmd.begin() + i);
break;
}
}
}
// 受伤动作不累积
// dodge动作不累积
if(pCommand->iType == _COMMAND_ACTION)
if(pCommand->nData == _ACTION_DODGE0 || pCommand->nData == _ACTION_BRUISE0)
{
if(m_infoPlayer.setCmd.size() != 0)
return false;
}
if(pCommand->iType == _COMMAND_INTONE && !pCommand->bAddUp)
{
if(m_infoPlayer.setCmd.size() != 0)
return false;
}
m_infoPlayer.setCmd.push_back(*pCommand);
if (_COMMAND_STANDBY != pCommand->iType)
{
// attack can be interrupted by Jump, Walk, Run, at any time.
if(_COMMAND_ATTACK == m_Info.cmdProc.iType ||
_COMMAND_SHOOT == m_Info.cmdProc.iType ||
_COMMAND_WOUND == m_Info.cmdProc.iType||
_COMMAND_DEFEND == m_Info.cmdProc.iType ||
_COMMAND_ACTION == m_Info.cmdProc.iType)
{
if(pCommand->iType == _COMMAND_WALK ||
pCommand->iType == _COMMAND_RUN ||
pCommand->iType == _COMMAND_JUMP)
this->ResetActionData();
}
// emotion, standby and action can be interrupted at any time.
if (_COMMAND_STANDBY == m_Info.cmdProc.iType
|| _COMMAND_EMOTION == m_Info.cmdProc.iType
|| _COMMAND_INTONE == m_Info.cmdProc.iType)
this->ResetActionData();
// cmd accomplished can be interrupted at andy time
if (_CMDSTATUS_ACCOMPLISH == m_Info.cmdProc.iStatus)
{
if (_ACTION_STANDBY == m_Info.iActType
|| _ACTION_ALERT == m_Info.iActType
|| _ACTION_REST1 == m_Info.iActType
|| _ACTION_REST2 == m_Info.iActType
|| _ACTION_REST3 == m_Info.iActType)
this->ResetActionData();
}
// die command can interrupt any command
if (_COMMAND_DIE == pCommand->iType)
this->ResetActionData();
}
memcpy(&(m_Info.cmdProc), pCommand, sizeof(CCommand));
return m_dwCommandIndex;
}
//--------------------------------------------------------------------------------------
void CPet::Jump(int nPosX, int nPosY)
{
int nCommandType = this->GetCommandType();
if(nCommandType == _COMMAND_ATTACK ||
nCommandType == _COMMAND_ACTION ||
nCommandType == _COMMAND_EMOTION ||
nCommandType == _COMMAND_WOUND ||
nCommandType == _COMMAND_DEFEND)
this->ResetActionData();
extern UINT g_uStatus;
if (_STATUS_NORMAL != g_uStatus)
return;
if (this->IsDead())
return;
CMyPos posTarget;
posTarget.x = nPosX;
posTarget.y = nPosY;
const OBJID idCanNotJump = 100022;
const OBJID idCanNotStay = 100023;
CMyPos posPet;
this->GetPos(posPet);
CONST MAX_JUMPDISTANCE = 16;
if (MAX_JUMPDISTANCE < g_objGameMap.GetDistance(posPet.x, posPet.y, nPosX, nPosY))
{
return;
}
if(!this->CanJump(posTarget))
{
g_objGameMsg.AddMsg((char*)g_objGameDataSet.GetStr(idCanNotJump));
return;
}
CellInfo* pCellInfo = g_objGameMap.GetCell(nPosX, nPosY);
CPlayer* pPlayer = g_objPlayerSet.GetPlayer(nPosX, nPosY);
if(!pCellInfo ||
g_objGameMap.GetGroundMask(pCellInfo) == 1 ||
(pPlayer && !pPlayer->IsDead()))
{
g_objGameMsg.AddMsg((char*)g_objGameDataSet.GetStr(idCanNotStay));
return;
}
if (posPet.x == nPosX && posPet.y == nPosY)
return;
// set command of role
CCommand cmd;
cmd.iType =_COMMAND_JUMP;
cmd.iStatus =_CMDSTATUS_BEGIN;
cmd.posTarget.x =nPosX;
cmd.posTarget.y =nPosY;
cmd.dwData =::TimeGet();
this->SetCommand(&cmd);
}
//--------------------------------------------------------------------------------------
BOOL CPet::ProcessCommand()
{
int iPosX, iPosY;
this->GetPos(iPosX, iPosY);
//--------------------------------------------------------
if(_COMMAND_JUMP == m_Info.cmdProc.iType)
{
if(_CMDSTATUS_BEGIN == m_Info.cmdProc.iStatus) // is a new jump cmd
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -