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

📄 objectmonster.cpp

📁 此为传奇游戏源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
      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 + -