📄 objectmonster.cpp
字号:
end;
end;
Result := 1;
end;
*/
void CMonsterObject::SearchViewRange()
{
int nX, nY;
PLISTNODE pListNode;
CMapCellInfo* pMapCellInfo;
_LPTOSOBJECT pOSObject;
CVisibleObject* pVisibleObject;
// Clear VisibleObjectList
if (m_xVisibleObjectList.GetCount())
{
PLISTNODE pListNode = m_xVisibleObjectList.GetHead();
while (pListNode)
{
if (pVisibleObject = m_xVisibleObjectList.GetData(pListNode))
pVisibleObject->nVisibleFlag = 0;
pListNode = m_xVisibleObjectList.GetNext(pListNode);
}
}
// Search VisibleObjectList
for (int i = 0; i < m_nViewRange; i++)
{
nX = m_nCurrX + g_SearchTable[i].x;
nY = m_nCurrY + g_SearchTable[i].y;
pMapCellInfo = m_pMap->GetMapCellInfo(nX, nY);
if (pMapCellInfo)
{
if (pMapCellInfo->m_xpObjectList)
{
if (pMapCellInfo->m_xpObjectList->GetCount())
{
pListNode = pMapCellInfo->m_xpObjectList->GetHead();
while (pListNode)
{
pOSObject = pMapCellInfo->m_xpObjectList->GetData(pListNode);
if (pOSObject)
{
if (pOSObject->btType == OS_MOVINGOBJECT)
{
CCharObject* pCharObject = (CCharObject*)pOSObject->pObject;
UpdateVisibleObject(pCharObject);
}
}
pListNode = pMapCellInfo->m_xpObjectList->GetNext(pListNode);
} // while (pListNode)
} // if (pMapCellInfo->m_pObjectList.GetCount())
}
} // if (pMapCellInfo)
}
if (m_xVisibleObjectList.GetCount())
{
PLISTNODE pListNode = m_xVisibleObjectList.GetHead();
while (pListNode)
{
if (pVisibleObject = m_xVisibleObjectList.GetData(pListNode))
{
if (pVisibleObject->nVisibleFlag == 0)
{
delete pVisibleObject;
pVisibleObject = NULL;
pListNode = m_xVisibleObjectList.RemoveNode(pListNode);
continue;
}
} // if (pVisibleObject = m_xVisibleObjectList.GetData(pListNode))
pListNode = m_xVisibleObjectList.GetNext(pListNode);
} // while (pListNode)
}
}
BOOL CMonsterObject::IsFrontObject(CCharObject* pCharObject)
{
for (int i = 0; i < 8; i++)
{
if (pCharObject->m_nCurrX == m_nCurrX + g_SearchTable[i].x && pCharObject->m_nCurrY == m_nCurrY + g_SearchTable[i].y)
return TRUE;
}
return FALSE;
}
void CMonsterObject::SetLastHiter(CCharObject* pHitter)
{
DWORD dwHitTick = GetTickCount();
m_pLastHitterObject = pHitter;
m_dwLastHitTime = dwHitTick;
if (!m_pExpHitterObject)
{
m_pExpHitterObject = pHitter;
m_dwExpHitTime = dwHitTick;
}
else
{
if (m_pExpHitterObject == pHitter)
m_dwExpHitTime = dwHitTick;
}
}
void CMonsterObject::Wondering()
{
if ((rand() % 20) == 0)
{
if ((rand() % 4) == 1)
TurnTo(rand() % 8);
else
WalkTo(m_nDirection);
}
}
void CMonsterObject::GotoTargetXY()
{
int nDir;
if ((m_nCurrX != m_nTargetX) || (m_nCurrY != m_nTargetY))
{
if (m_xVisibleObjectList.GetCount())
{
PLISTNODE pListNode = m_xVisibleObjectList.GetHead();
CVisibleObject* pVisibleObject = m_xVisibleObjectList.GetData(pListNode);
if (pVisibleObject)
{
if ((!pVisibleObject->pObject->m_fIsDead) && IsProperTarget(pVisibleObject->pObject) && (!pVisibleObject->pObject->m_fInspector))
{
if (abs(m_nCurrX - pVisibleObject->pObject->m_nCurrX) + abs(m_nCurrY - pVisibleObject->pObject->m_nCurrY) <
abs(m_nCurrX - m_nTargetX) + abs(m_nCurrY - m_nTargetY))
{
SelectTarget(pVisibleObject->pObject);
m_nTargetX = pVisibleObject->pObject->m_nCurrX;
m_nTargetY = pVisibleObject->pObject->m_nCurrY;
return;
}
}
}
}
int nX = m_nTargetX;
int nY = m_nTargetY;
m_nFindPathTime = GetTickCount();
while (TRUE)
{
if (nX > m_nCurrX)
{
nDir = DR_RIGHT;
if (nY > m_nCurrY)
nDir = DR_DOWNRIGHT;
else if (nY < m_nCurrY)
nDir = DR_UPRIGHT;
break;
}
if (nX < m_nCurrX)
{
nDir = DR_LEFT;
if (nY > m_nCurrY)
nDir = DR_DOWNLEFT;
else if (nY < m_nCurrY)
nDir = DR_UPLEFT;
break;
}
if (nY > m_nCurrY)
{
nDir = DR_DOWN;
break;
}
if (nY < m_nCurrY)
{
nDir = DR_UP;
break;
}
break;
}
// char szTemp[64];
// sprintf(szTemp, "捞 仇 %s 具 芭扁 几芭扼... 窍窍窍", m_pTargetObject->m_szName);
// AddRefMsg(RM_MONSTERSAY, 0, 0, 0, 0, szTemp);
int nOldX = m_nCurrX;
int nOldY = m_nCurrY;
WalkTo(nDir);
for (int i = 0; i < 7; i++)
{
if (nOldX == m_nCurrX && nOldY == m_nCurrY)
{
if (rand() % 3) nDir++;
else if (nDir > 0) nDir--;
else
nDir = 7;
if (nDir > 7) nDir = 0;
WalkTo(nDir);
}
else
break;
}
}
}
void CMonsterObject::Struck(CCharObject* pHitter)
{
if (pHitter)
{
if (IsProperTarget(pHitter))
SelectTarget(pHitter);
}
if (m_Ability.Level < 50)
m_dwHitTime = m_dwHitTime + (150 - _MIN(130, m_Ability.Level * 4));
/*procedure TAnimal.Struck (hiter: TCreature);
begin
StruckTime := GetTickCount;
if hiter <> nil then begin
if IsProperTarget (hiter) then
SelectTarget (hiter);
end;
if BoAnimal then begin
MeatQuality := MeatQuality - Random (300); //悼拱捞 嘎栏搁 嘎阑 荐废 绊扁 前龙捞 冻绢咙
if MeatQuality < 0 then MeatQuality := 0;
end;
if Abil.Level < 50 then
HitTime := HitTime + (150 - _MIN(130, Abil.Level * 4)); //茄规俊 ms究 词霸 锭赴促.
//WalkTime := WalkTime + (300 - _MIN(200, (Abil.Level div 5) * 20));
end;
*/
}
WORD CMonsterObject::GetThisCharColor()
{
if (m_fBoHolySeize)
return _CHAT_COLOR4;
return _CHAT_COLOR3;
}
void CMonsterObject::Operate()
{
int nCount = m_DelayProcessQ.GetCount();
_LPTPROCESSMSG lpProcessMsg;
if (nCount)
{
for (int i = 0; i < nCount; i++)
{
lpProcessMsg = (_LPTPROCESSMSG)m_DelayProcessQ.PopQ();
if (lpProcessMsg)
{
if (GetTickCount() < lpProcessMsg->dwDeliveryTime)
{
m_DelayProcessQ.PushQ((BYTE *)lpProcessMsg);
continue;
}
switch (lpProcessMsg->wIdent)
{
case RM_DOOPENHEALTH:
{
MakeOpenHealth();
break;
}
case RM_STRUCK:
{
if (lpProcessMsg->pCharObject->m_wObjectType & _OBJECT_HUMAN)
lpProcessMsg->pCharObject->AddRefMsg(RM_STRUCK, lpProcessMsg->wParam, lpProcessMsg->lParam1,
lpProcessMsg->lParam2, lpProcessMsg->lParam3, NULL);
break;
}
case RM_MAGSTRUCK:
{
AddProcess(lpProcessMsg->pCharObject, lpProcessMsg->wIdent, lpProcessMsg->wParam, lpProcessMsg->lParam1,
lpProcessMsg->lParam2, lpProcessMsg->lParam3, NULL);
break;
}
}
delete lpProcessMsg;
lpProcessMsg = NULL;
}
}
}
nCount = m_ProcessQ.GetCount();
if (nCount)
{
for (int i = 0; i < nCount; i++)
{
lpProcessMsg = (_LPTPROCESSMSG)m_ProcessQ.PopQ();
switch (lpProcessMsg->wIdent)
{
case RM_STRUCK:
{
if (lpProcessMsg->pCharObject == this && lpProcessMsg->lParam3)
{
SetLastHiter((CCharObject*)lpProcessMsg->lParam3);
Struck((CCharObject*)lpProcessMsg->lParam3);
m_dwHealthTick = 0;
m_dwSpellTick = 0;
m_btPerHealth--;
m_btPerSpell--;
BreakHolySeize();
}
break;
}
case RM_MAGSTRUCK:
case RM_MAGSTRUCK_MINE:
{
if (lpProcessMsg->wIdent == RM_MAGSTRUCK)
{
if (m_Ability.Level < 50)
m_dwWalkTime += 800 + (rand() % 1000);
}
int nVal = GetMagStruckDamage(lpProcessMsg->lParam1);
if (nVal > 0)
{
StruckDamage(nVal);
HealthSpellChanged();
AddRefMsg(RM_STRUCK_MAG, nVal, m_WAbility.HP, m_WAbility.MP, (int)lpProcessMsg->pCharObject, NULL);
// if BoAnimal then begin //绊扁啊 唱坷绰 悼拱牢 版快..
// MeatQuality := MeatQuality - v1 * 1000; //付过阑 嘎栏搁 绊扁龙捞 摹疙利栏肺 唱狐柳促.
// end;
SetLastHiter(lpProcessMsg->pCharObject);
// Struck(lpProcessMsg->pCharObject);
m_dwHealthTick = 0;
m_dwSpellTick = 0;
BreakHolySeize();
}
break;
}
}
delete lpProcessMsg;
lpProcessMsg = NULL;
}
}
Run();
}
void CMonsterObject::MonsterNormalAttack()
{
if (m_xVisibleObjectList.GetCount())
{
PLISTNODE pListNode = m_xVisibleObjectList.GetHead();
while (pListNode)
{
CVisibleObject* pVisibleObject = m_xVisibleObjectList.GetData(pListNode);
if (pVisibleObject)
{
if ((!pVisibleObject->pObject->m_fIsDead) && IsProperTarget(pVisibleObject->pObject)
&& (!pVisibleObject->pObject->m_fInspector) && (!pVisibleObject->pObject->m_fHumHideMode))
{
if (abs(m_nCurrX - pVisibleObject->pObject->m_nCurrX) + abs(m_nCurrY - pVisibleObject->pObject->m_nCurrY) < 999)
{
SelectTarget(pVisibleObject->pObject);
return;
}
}
}
pListNode = m_xVisibleObjectList.GetNext(pListNode);
}
}
}
BOOL CMonsterObject::TargetInAttackRange()
{
if (m_pTargetObject)
{
if ((m_pTargetObject->m_nCurrX >= m_nCurrX - 1) && (m_pTargetObject->m_nCurrX <= m_nCurrX + 1) &&
(m_pTargetObject->m_nCurrY >= m_nCurrY - 1) && (m_pTargetObject->m_nCurrY <= m_nCurrY + 1) &&
!((m_pTargetObject->m_nCurrX == m_nCurrX) && (m_pTargetObject->m_nCurrY == m_nCurrY)))
{
if ((m_pTargetObject->m_nCurrX == m_nCurrX - 1) && (m_pTargetObject->m_nCurrY == m_nCurrY))
{
m_btTargetDir = DR_LEFT;
return TRUE;
}
if ((m_pTargetObject->m_nCurrX == m_nCurrX + 1) && (m_pTargetObject->m_nCurrY == m_nCurrY))
{
m_btTargetDir = DR_RIGHT;
return TRUE;
}
if ((m_pTargetObject->m_nCurrX == m_nCurrX) && (m_pTargetObject->m_nCurrY == m_nCurrY - 1))
{
m_btTargetDir = DR_UP;
return TRUE;
}
if ((m_pTargetObject->m_nCurrX == m_nCurrX) && (m_pTargetObject->m_nCurrY == m_nCurrY + 1))
{
m_btTargetDir = DR_DOWN;
return TRUE;
}
if ((m_pTargetObject->m_nCurrX == m_nCurrX - 1) && (m_pTargetObject->m_nCurrY == m_nCurrY - 1))
{
m_btTargetDir = DR_UPLEFT;
return TRUE;
}
if ((m_pTargetObject->m_nCurrX == m_nCurrX + 1) && (m_pTargetObject->m_nCurrY == m_nCurrY - 1))
{
m_btTargetDir = DR_UPRIGHT;
return TRUE;
}
if ((m_pTargetObject->m_nCurrX == m_nCurrX - 1) && (m_pTargetObject->m_nCurrY == m_nCurrY + 1))
{
m_btTargetDir = DR_DOWNLEFT;
return TRUE;
}
if ((m_pTargetObject->m_nCurrX == m_nCurrX + 1) && (m_pTargetObject->m_nCurrY == m_nCurrY + 1))
{
m_btTargetDir = DR_DOWNRIGHT;
return TRUE;
}
}
}
return FALSE;
}
BOOL CMonsterObject::TargetInSpitRange(int& nTargetDir)
{
int nX = 0, nY = 0;
if ((abs(m_pTargetObject->m_nCurrX - m_nCurrX) <= 2) && (abs(m_pTargetObject->m_nCurrY - m_nCurrY) <= 2))
{
nX = m_pTargetObject->m_nCurrX - m_nCurrX;
nY = m_pTargetObject->m_nCurrY - m_nCurrY;
if ((abs(nX) <= 1) && (abs(nY) <= 1))
{
TargetInAttackRange();
return TRUE;
}
else
{
nX += 2;
nY += 2;
if ((nX >= 0 && nX <= 4) && (nY >= 0 && nY <= 4))
{
nTargetDir = GetNextDirection(m_pTargetObject->m_nCurrX, m_pTargetObject->m_nCurrY);
if (g_SpitMap[nTargetDir][nX][nY] == 1)
return TRUE;
}
}
}
return FALSE;
}
BOOL CMonsterObject::Attack()
{
m_nDirection = (int)m_btTargetDir;
_Attack(CM_HIT, m_pTargetObject);
AddRefMsg(RM_HIT, m_nDirection, m_nCurrX, m_nCurrY, 0, NULL);
return TRUE;
}
BOOL CMonsterObject::AttackTarget()
{
if (m_pTargetObject)
{
if (TargetInAttackRange())
{
if (GetTickCount() - m_dwHitTime > m_dwNextHitTime)
{
m_dwHitTime = m_dwTargetFocusTime = GetTickCount();
Attack();
BreakHolySeize();
}
return TRUE;
}
else
{
if (m_pTargetObject->m_pMap == m_pMap)
{
m_nTargetX = m_pTargetObject->m_nCurrX;
m_nTargetY = m_pTargetObject->m_nCurrY;
}
else
{
m_pTargetObject = NULL;
m_nTargetX = -1;
m_nTargetY = -1;
}
}
}
return FALSE;
}
BOOL CMonsterObject::Think()
{
if (GetTickCount() - m_dwThinkTime > 3000)
{
m_dwThinkTime = GetTickCount();
if (m_pMap->GetDupCount(m_nCurrX, m_nCurrY) >= 2)
m_fDupMode = TRUE;
if (m_pTargetObject)
{
if (!IsProperTarget(m_pTargetObject))
m_pTargetObject = NULL;
}
}
if (m_fDupMode)
{
int nOldX = m_nCurrX;
int nOldY = m_nCurrY;
WalkTo(rand() % 8);
if (nOldX != m_nCurrX || nOldX != m_nCurrX)
{
m_fDupMode = FALSE;
return TRUE;
}
}
return FALSE;
}
void CMonsterObject::InheritedRun()
{
if (RestoreHealSpell())
Die();
CCharObject::Run();
}
void CMonsterObject::Run()
{
if (!m_fIsDead && !m_fHideMode && !m_fIsGhost && !m_fStoneMode && m_wStatusArr[POISON_STONE] == 0)
{
if (m_pTargetObject)
{
if ((GetTickCount() - m_dwTargetFocusTime > 30000) || m_pTargetObject->m_fIsDead || m_pTargetObject->m_fIsGhost ||
(abs(m_pTargetObject->m_nCurrX - m_nCurrX) > 15) || (abs(m_pTargetObject->m_nCurrY - m_nCurrY) > 15))
m_pTargetObject = NULL;
}
/* if LastHiter <> nil then begin
if (GetTickCount - LastHitTime > 30 * 1000) or
(LastHiter.Death) or
(LastHiter.BoGhost) then
LastHiter := nil;
end;
if ExpHiter <> nil then begin
if (GetTickCount - ExpHitTime > 6 * 1000) or
(ExpHiter.Death) or
(ExpHiter.BoGhost) then
ExpHiter := nil;
end;
if Master <> nil then begin
BoNoItem := TRUE;
if (Master.Death and (GetTickCount - Master.DeathTime > 1000)) or
(Master.BoGhost and (GetTickCount - Master.GhostTime > 1000)) then begin
WAbil.HP := 0; //Die;
//Master := nil;
end;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -