#include "stdafx.h" #include #include #include #include #include #include #include #include #include #include "Monster.h" #include "PatternMonster.h" //--------------------------------------------------------------------------------------- // ±âº» ¸ó½ºÅÍ /////////////////////////////////////////////////////////////////////////////////// // Function : CMonster::CheckPartyTarget // // Description : ¸ó½ºÅÍ ÆÄƼÀÇ Å¸°ÙÀ» Ã¼Å©ÇØ¼­ °¡Àå °¡±î¿î ŸÄÏÀ» °ø°ÝÇÑ´Ù. // // Inputs : None. // // Outputs : None. // // Returns : Attack ÇൿÀ¸·Î º¯°æµÇ¸é true ¸®ÅÏ, Çൿ¿¡ º¯È­°¡ ¾øÀ¸¸é false ¸®ÅÏ /////////////////////////////////////////////////////////////////////////////////// bool CMonster::CheckPartyTarget(void) { CMonsterParty* lpParty = reinterpret_cast(GetParty()); if (NULL == lpParty) { return false; } CMonsterParty::PartyTargetSet& targetSet = lpParty->GetPartyTargetSet(); if (true == targetSet.empty()) { return false; } typedef std::map DistanceTargetMap; CAggresiveCreature* lpTarget = NULL; DistanceTargetMap attackTargetMap; CMonsterParty::PartyTargetSet::iterator itr = targetSet.begin(); CMonsterParty::PartyTargetSet::iterator end = targetSet.end(); for (; itr != end; ) { unsigned long dwTargetCID = *itr; // ¾ø´Â Å©¸®ÃÄÀÎÁö üũ if (0 != GetMapIndex()) { VirtualArea::CVirtualArea* lpVirtualArea = VirtualArea::CVirtualAreaMgr::GetInstance().GetVirtualArea(GetMapIndex()); if (NULL != lpVirtualArea) { CVirtualMonsterMgr* lpVirtualMonsterMgr = lpVirtualArea->GetMonsterManager(); if (NULL != lpVirtualMonsterMgr) { lpTarget = lpVirtualMonsterMgr->GetAggresiveCreature(dwTargetCID); } } } else { lpTarget = CCreatureManager::GetInstance().GetAggresiveCreature(dwTargetCID); } if (NULL == lpTarget || true == lpTarget->GetEnchantInfo().GetFlag(Skill::SpellID::Hide)) { itr = targetSet.erase(itr); } else { const Position& targetPos = lpTarget->GetCurrentPos(); // °Å¸® °è»ê float fSquareTargetDistance = (m_CurrentPos.m_fPointX - targetPos.m_fPointX) * (m_CurrentPos.m_fPointX - targetPos.m_fPointX) + (m_CurrentPos.m_fPointZ - targetPos.m_fPointZ) * (m_CurrentPos.m_fPointZ - targetPos.m_fPointZ); float fSquareHelpDistance = (lpParty->GetHelpRange() * lpParty->GetHelpRange()); if (fSquareTargetDistance <= fSquareHelpDistance) { attackTargetMap.insert(make_pair(fSquareTargetDistance, lpTarget)); } ++itr; } } // °Å¸®°¡ °¡Àå °¡±î¿î Ÿ°ÙÀ» °¡Á®¿Â´Ù. if (false == attackTargetMap.empty()) { const float fAttackRange = m_MonsterInfo.m_wAttackRange / 100.0f; DistanceTargetMap::iterator itr = attackTargetMap.begin(); const float fDistance = sqrtf(itr->first); lpTarget = itr->second; m_Threat.AddToThreatList(lpTarget, 1); m_nCurrentState = CFSM::GetInstance().StateTransition(m_nCurrentState, INPUT_ID_SEEN_PLAYER); if (fAttackRange < fDistance || GetPattern() == MonsterInfo::PATTERN_MAGE || GetPattern() == MonsterInfo::PATTERN_ACOLYTE) { m_bLongRangeAttacked = true; } return true; } return false; } /////////////////////////////////////////////////////////////////////////////////// // Function : CMonster::SearchPlayer // // Description : Áö¿ª³» Ç÷¹À̾î ã±â // // Inputs : None. // // Outputs : None. // // Returns : None. /////////////////////////////////////////////////////////////////////////////////// void CMonster::SearchPlayer(void) { // TODO : ÇØ»óµµ Á¶ÀýÀ» ÅëÇØ float °è»êÀ» ¾ø¾Öº¸ÀÚ. if (NULL == m_CellPos.m_lpCell) { ERRLOG1(g_Log, "CID:0X%08 ¸ó½ºÅͰ¡ ¼¿ ¹üÀ§ ¹Û¿¡ ÀÖ½À´Ï´Ù.", m_dwCID); return; } CCell* pCell = NULL; CCharacter* pTempTarget = NULL; CCharacter* pCurrentTarget = NULL; const float fSquareSearchRange = (float)(m_wSearchRange * m_wSearchRange); for (int nCellCount = 0; nCellCount < CCell::CONNECT_NUM; ++nCellCount) { pCell = m_CellPos.m_lpCell->GetConnectCell(nCellCount); if (NULL == pCell || false == pCell->IsCharacter()) { continue; } pTempTarget = pCell->GetFirstCharacter(); while (NULL != pTempTarget) { if (pTempTarget->GetStatus().m_nNowHP > 0 && false == pTempTarget->IsRideArms()) { if (false == pTempTarget->GetEnchantInfo().GetFlag(Skill::SpellID::Stealth) && false == pTempTarget->GetEnchantInfo().GetFlag(Skill::SpellID::Invincible) && false == pTempTarget->GetEnchantInfo().GetFlag(Skill::SpellID::Hide)) { const float fDX = pTempTarget->GetCurrentPos().m_fPointX - GetCurrentPos().m_fPointX; const float fDZ = pTempTarget->GetCurrentPos().m_fPointZ - GetCurrentPos().m_fPointZ; const float fDistance = (fDX * fDX) + (fDZ * fDZ); if (fDistance < fSquareSearchRange) { // edith 2008.02.13 ¼±°ø¸÷ ó¸®È®À² // ·¹º§Â÷¿¡ µû¸¥ ¼±°ø È®·ü // ·¹º§ °¸À» ¸®ÅÏÇÑ´Ù. // if ((CalculateLevelGap(pTempTarget) + 10) * 2 > static_cast(Math::Random::ComplexRandom(100))) int iGap = CalculateLevelGap(pTempTarget); if(pTempTarget->GetAbilityValue(Skill::Type::AB_NOFIRSTATK)) { // ¼±°ø ±ÝÁö ¾îºô¸®Æ¼ if ( iGap > pTempTarget->GetAbilityValue(Skill::Type::AB_NOFIRSTATK)) { pCurrentTarget = pTempTarget; break; } } else { // 100ÆÛ¼¾Æ® ¼±°ø if ( iGap >= 0) { pCurrentTarget = pTempTarget; break; } else if( iGap >= -5 && static_cast(Math::Random::ComplexRandom(2)) == 1) { // 50ÇÁ·Î ¼±°ø pCurrentTarget = pTempTarget; break; } } } } } pTempTarget = pCell->GetNextCharacter(); } } if (NULL != pCurrentTarget) { m_Threat.AddToThreatList(pCurrentTarget, 1); m_nCurrentState = CFSM::GetInstance().StateTransition(m_nCurrentState, INPUT_ID_SEEN_PLAYER); } } void CMonster::NormalBehavior(unsigned long dwTick) { PERFORMANCE_CHECK(FunctionTimingCheck) if (m_nLeaveMovingNum != 0) { m_nLeaveMovingNum--; if (F_CELL_CANNOTCHANGE == MoveTo(CalculateCoor(), false)) { ms_NormalBehaviorSendCount += SendMove(RUN_ANI_LIMIT_MIN); m_nLeaveMovingNum = 0; } m_lCurrentFrame = m_MotionInfo.m_dwFrame; return; } // ÆÄƼ°¡ ÀÖ°í, ÆÄƼ°¡ ½Î¿ì°í ÀÖ´Ù¸é... // ½Î¿ì´Â »ó´ëÁß ÀÏÁ¤ ¹üÀ§ ³»¿¡¼­.. Àڽſ¡°Ô °¡±î¿î ³à¼®¿¡°Ô ´Þ·Á°£´Ù. // ÀÚ½ÅÀÇ ½Ã¾ß ¾È¿¡ µé¾î¿À¸é Threat ¸®½ºÆ®¿¡ ÇØ´ç ¸ó½ºÅ͸¦ Ãß°¡Çϰí, // Attack »óÅ·Π¸¸µç´Ù. if (GetParty()) { if (CheckPartyTarget()) return; } // ¼±°ø ¸÷ ó¸® if (NULL == m_lpTarget && true == m_MonsterInfo.m_bFirstAttack) { SearchPlayer(); } // TODO : À̵¿ ÆÐÅÏ¿¡ µû¸¥ ó¸® (·çÆ®ÇüÀÌ ¾ÆÁ÷ ¹Ì°á) if (CCellManager::GetInstance().IsMoving() && m_nNormalMovingDelay <= 0 && CCellManager::GetInstance().GetMovingNum() > Math::Random::ComplexRandom(100)) { const float fOriginalDX = m_OriginalPosition.m_fPointX - GetCurrentPos().m_fPointX; const float fOriginalDZ = m_OriginalPosition.m_fPointZ - GetCurrentPos().m_fPointZ; const float fOriginalDistance = (fOriginalDX * fOriginalDX) + (fOriginalDZ * fOriginalDZ); if (fOriginalDistance > (MoveRange * MoveRange) && m_nMovingPattern == AREA) { m_MotionInfo.m_wAction = MonsterInfo::Z3D_CA_RUN; GetMotion(m_MotionInfo.m_wAction, m_MotionInfo); m_MotionInfo.m_fDirection = CalcDir2D(GetCurrentPos().m_fPointX, GetCurrentPos().m_fPointZ, m_OriginalPosition.m_fPointX, m_OriginalPosition.m_fPointZ); } else { m_MotionInfo.m_wAction = MonsterInfo::Z3D_CA_WALK; GetMotion(m_MotionInfo.m_wAction, m_MotionInfo); m_MotionInfo.m_fDirection = (Math::Random::ComplexRandom(62832)) / 10000.0f; } if (m_nMovingPattern == FIXED) { m_MotionInfo.m_fDirection = 0; m_MotionInfo.m_fVelocity = 0; } m_nNormalMovingDelay = SendMove(RUN_ANI_LIMIT_MAX); ms_NormalBehaviorSendCount += m_nNormalMovingDelay; m_nLeaveMovingNum--; MoveTo(CalculateCoor(), false); m_lCurrentFrame = m_MotionInfo.m_dwFrame; } else { m_nNormalMovingDelay -= RATE_MOVING_AND_PLAYER; m_lCurrentFrame = FPS; } } void CMonster::AttackBehavior(unsigned long dwTick) { PERFORMANCE_CHECK(FunctionTimingCheck) m_lpTarget = m_Threat.GetTarget(); if (NULL == m_lpTarget || MonsterInfo::PATTERN_BG == m_MonsterInfo.m_cSkillPattern) { CancelTarget(); return; } else if (m_lpTarget && true == m_lpTarget->GetEnchantInfo().GetFlag(Skill::SpellID::Hide)) { CancelTarget(); return; } // º´±â¿¡ ž½ÂÇÑ Ä³¸¯ÅÍ´Â ¶§¸®Áö ¾Ê´Â´Ù. if (Creature::CT_PC == Creature::GetCreatureType(m_lpTarget->GetCID())) { CCharacter* lpTargetChar = reinterpret_cast(m_lpTarget); if (lpTargetChar->IsRideArms()) { CancelTarget(); return; } } const float fDX = m_lpTarget->GetCurrentPos().m_fPointX - GetCurrentPos().m_fPointX; const float fDZ = m_lpTarget->GetCurrentPos().m_fPointZ - GetCurrentPos().m_fPointZ; const float fDistance = sqrtf((fDX * fDX) + (fDZ * fDZ)); // °Ë»öÇÒ¼ö ÀÖ´Â ¿µ¿ªº¸´Ù ³Ð°Å³ª HP°¡ 0À̸é ĵ½½ÇÑ´Ù. if (((fDistance > m_wSearchRange) && false == m_bLongRangeAttacked) || (0 == m_lpTarget->GetStatus().m_nNowHP)) { CancelTarget(); return; } // ÆÄƼÀÇ Å¸°ÙÀ¸·Î Áý¾î ³Ö´Â´Ù. CMonsterParty* lpParty = reinterpret_cast(GetParty()); if (NULL != lpParty) { // ·¹º§Â÷À̰¡ ³Ê¹« ³ª¸é ÆÄƼÀÇ Å¸°ÙÀ¸·Î Áý¾î³ÖÁö ¾Ê´Â´Ù. if (lpParty->GetHighestLevel() + CMonsterParty::ERROR_OF_LEVEL_GAP > m_lpTarget->GetStatus().m_nLevel) { lpParty->GetPartyTargetSet().insert(m_lpTarget->GetCID()); // set ¿¡¼­ ¾ø¾îÁö´Â °ÍÀº CancelTarget ¿¡¼­ ó¸®ÇÑ´Ù. } else if (GetPattern() == MonsterInfo::PATTERN_BOSS || GetPattern() == MonsterInfo::PATTERN_NAMED || GetPattern() == MonsterInfo::PATTERN_CHIEF) { lpParty->GetPartyTargetSet().insert(m_lpTarget->GetCID()); // set ¿¡¼­ ¾ø¾îÁö´Â °ÍÀº CancelTarget ¿¡¼­ ó¸®ÇÑ´Ù. } } const float fAttackRange = m_MonsterInfo.m_wAttackRange / 100.0f; if (fDistance > fAttackRange && 0 >= m_lCurrentFrame) { // °ø°Ý ¹üÀ§ ¹ÛÀÌ´Ù. m_MotionInfo.m_wAction = MonsterInfo::Z3D_CA_WALK; // ÀÏ´Ü °È±â·Î ¼¼ÆÃ GetMotion(m_MotionInfo.m_wAction, m_MotionInfo); // °È±â ¸ð¼Ç Á¤º¸¸¦ ¾ò¾î¿Â´Ù. // ¸ó½ºÅͰ¡ À̵¿ °ø°ÝÀ» ÇÒ¸¸ÇÑ °Å¸®Àΰ¡ üũ if (fDistance < fAttackRange + m_MotionInfo.m_fVelocity) { // edith 2009.08.06 °ø°Ý½Ã °É¾î¼­ °ø°ÝÀ» ¾ø¾Ø´Ù. // ´Þ·Á°£´Ù RunAction(fDistance, m_lpTarget->GetCurrentPos().m_fPointX, m_lpTarget->GetCurrentPos().m_fPointZ); // °É¾î°¡¸é¼­ °ø°Ý // WalkAttackAction(fDistance - fAttackRange + 0.1f); // ³» Ȱµ¿±¸¿ªÀ» ¹þ¾î³ªµû. µ¹¾Æ°¡ÀÚ~! if (true == m_MonsterInfo.m_bReturnPosition && true == IsReturn()) { m_wSearchRange = OutsideSearchRange; CancelTarget(); } } else { // ´Þ·Á°£´Ù RunAction(fDistance, m_lpTarget->GetCurrentPos().m_fPointX, m_lpTarget->GetCurrentPos().m_fPointZ); // ³» Ȱµ¿±¸¿ªÀ» ¹þ¾î³ªµû. µ¹¾Æ°¡ÀÚ~! if (true == m_MonsterInfo.m_bReturnPosition && true == IsReturn()) { m_wSearchRange = OutsideSearchRange; CancelTarget(); } } if (false == m_bAttacking) { m_lCurrentFrame = m_MotionInfo.m_dwFrame; } } else { // °ø°Ý ¹üÀ§ ¾ÈÀÌ´Ù. if (false == m_bAttacking) { AttackAction(); } } } void CMonster::ReturnBehavior(unsigned long dwTick) { PERFORMANCE_CHECK(FunctionTimingCheck) if (m_nLeaveMovingNum <= 0) { m_MotionInfo.m_wAction = MonsterInfo::Z3D_CA_RUN; GetMotion(m_MotionInfo.m_wAction, m_MotionInfo); const float fOriginalDX = m_OriginalPosition.m_fPointX - GetCurrentPos().m_fPointX; const float fOriginalDZ = m_OriginalPosition.m_fPointZ - GetCurrentPos().m_fPointZ; const float fOriginalDistance = (fOriginalDX * fOriginalDX) + (fOriginalDZ * fOriginalDZ); m_MotionInfo.m_fDirection = CalcDir2D(GetCurrentPos().m_fPointX, GetCurrentPos().m_fPointZ, m_OriginalPosition.m_fPointX, m_OriginalPosition.m_fPointZ); unsigned short nAniNum = (unsigned short)(sqrtf(fOriginalDistance) / m_MotionInfo.m_fVelocity); nAniNum = (nAniNum > RUN_ANI_LIMIT_MAX) ? RUN_ANI_LIMIT_MAX : nAniNum; if (nAniNum == 0) { m_wSearchRange = m_wDefaultSearchRange; m_nCurrentState = CFSM::GetInstance().StateTransition(m_nCurrentState, INPUT_ID_ARRIVAL_SITE); m_Threat.ClearThreatList(); CancelTarget(); return; } ms_ReturnBehaviorSendCount += SendMove(nAniNum); } m_nLeaveMovingNum--; if (F_CELL_CANNOTCHANGE == MoveTo(CalculateCoor(), false)) { ms_ReturnBehaviorSendCount += SendMove(RUN_ANI_LIMIT_MIN); m_nLeaveMovingNum = 0; } m_lCurrentFrame = m_MotionInfo.m_dwFrame; } void CMonster::EscapeBehavior(void) { PERFORMANCE_CHECK(FunctionTimingCheck) if (NULL == m_lpTarget) { m_nCurrentState = CFSM::GetInstance().StateTransition(m_nCurrentState, INPUT_ID_LEAVE_PLAYER); return; } m_MotionInfo.m_wAction = MonsterInfo::Z3D_CA_RUN; GetMotion(m_MotionInfo.m_wAction, m_MotionInfo); m_MotionInfo.m_fDirection = CalcDir2D(GetCurrentPos().m_fPointX, GetCurrentPos().m_fPointZ, m_lpTarget->GetCurrentPos().m_fPointX, m_lpTarget->GetCurrentPos().m_fPointZ); m_MotionInfo.m_fDirection += Math::Const::PI; if (m_MotionInfo.m_fDirection >= (Math::Const::PI * 2.0f)) { m_MotionInfo.m_fDirection -= (Math::Const::PI * 2.0f); } ms_EscapeBehaviorSendCount += SendMove(RUN_ANI_LIMIT_MIN); MoveTo(CalculateCoor(), false); m_nLeaveMovingNum = 0; m_lCurrentFrame = m_MotionInfo.m_dwFrame; } void CMonster::DeadBehavior(unsigned long dwTick) { PERFORMANCE_CHECK(FunctionTimingCheck) if (dwTick < m_dwLastTime + m_MonsterInfo.m_dwRespawnTime) { m_lCurrentFrame = FPS; return; } // m_Threat.ClearThreatList(); // CancelTarget(); m_nLeaveMovingNum = 0; Respawn(dwTick); } //--------------------------------------------------------------------------------------- // ¼Òȯ ¸ó½ºÅÍ void CSummonMonster::NormalBehavior(unsigned long dwTick) { if (NULL == m_lpMaster) { CMonster::NormalBehavior(dwTick); return; } --m_nLeaveMovingNum; if (0 >= m_nLeaveMovingNum) { const float fDX = m_lpMaster->GetCurrentPos().m_fPointX - GetCurrentPos().m_fPointX; const float fDZ = m_lpMaster->GetCurrentPos().m_fPointZ - GetCurrentPos().m_fPointZ; const float fDistance = sqrtf((fDX * fDX) + (fDZ * fDZ)); if (fDistance <= SUPPORT_DISTANCE) { return; } m_MotionInfo.m_wAction = MonsterInfo::Z3D_CA_RUN; GetMotion(m_MotionInfo.m_wAction, m_MotionInfo); m_MotionInfo.m_fDirection = CalcDir2D(GetCurrentPos().m_fPointX, GetCurrentPos().m_fPointZ, m_lpMaster->GetCurrentPos().m_fPointX, m_lpMaster->GetCurrentPos().m_fPointZ); unsigned short nAniNum = static_cast(fDistance / m_MotionInfo.m_fVelocity); nAniNum = (nAniNum > RUN_ANI_LIMIT_MAX) ? RUN_ANI_LIMIT_MAX : nAniNum; if (0 == nAniNum) { return; } ms_NormalBehaviorSendCount += SendMove(nAniNum); } if (F_CELL_CANNOTCHANGE == MoveTo(CalculateCoor(), false)) { m_nLeaveMovingNum = 0; ms_ReturnBehaviorSendCount += SendMove(RUN_ANI_LIMIT_MIN); } m_lCurrentFrame = m_MotionInfo.m_dwFrame; } void CSummonMonster::AttackBehavior(unsigned long dwTick) { if (NULL != m_lpMaster) { m_OriginalPosition = m_lpMaster->GetCurrentPos(); } CMonster::AttackBehavior(dwTick); } void CSummonMonster::ReturnBehavior(unsigned long dwTick) { m_nCurrentState = CFSM::GetInstance().StateTransition(m_nCurrentState, INPUT_ID_ARRIVAL_SITE); m_Threat.ClearThreatList(); CancelTarget(); } void CSummonMonster::DeadBehavior(unsigned long dwTick) { // ¼Òȯ ¸ó½ºÅÍ´Â »ç¸ÁÇÏ¸é »èÁ¦µÉ ¶§±îÁö ´ë±âÇÑ´Ù. »èÁ¦´Â ¸ÞÀÎ ·çÇÁ¿¡¼­ Àϰý ó¸®ÇÑ´Ù. } //--------------------------------------------------------------------------------------- // ¸í¿¹ÀÇ ¼®»ó void CStatue::NormalBehavior(unsigned long dwTick) { unsigned char cServerZone = CServerSetup::GetInstance().GetServerZone(); if (SERVER_ID::ZONE3 == cServerZone || SERVER_ID::STATUE_ZONE == cServerZone) { CCreatureManager::GetInstance().ProcessAllCharacter(CStatueInfo(this, false, 0)); } // 1·¹º§ if (MonsterInfo::STATUE_HUMAN_LOADING1 == m_MonsterInfo.m_dwKID || MonsterInfo::STATUE_AKHAN_LOADING1 == m_MonsterInfo.m_dwKID || MonsterInfo::POWER_STATUE_HUMAN_LOADING1 == m_MonsterInfo.m_dwKID || MonsterInfo::POWER_STATUE_AKHAN_LOADING1 == m_MonsterInfo.m_dwKID || MonsterInfo::INT_STATUE_HUMAN_LOADING1 == m_MonsterInfo.m_dwKID || MonsterInfo::INT_STATUE_AKHAN_LOADING1 == m_MonsterInfo.m_dwKID || MonsterInfo::EXP_STATUE_HUMAN_LOADING1 == m_MonsterInfo.m_dwKID || MonsterInfo::EXP_STATUE_AKHAN_LOADING1 == m_MonsterInfo.m_dwKID || MonsterInfo::WEALTH_STATUE_HUMAN_LOADING1 == m_MonsterInfo.m_dwKID || MonsterInfo::WEALTH_STATUE_AKHAN_LOADING1 == m_MonsterInfo.m_dwKID || MonsterInfo::LIFE_EXTRACT_HUMAN_LOADING1 == m_MonsterInfo.m_dwKID || MonsterInfo::LIFE_EXTRACT_AKHAN_LOADING1 == m_MonsterInfo.m_dwKID || //2·¹º§ MonsterInfo::STATUE_HUMAN_LOADING2 == m_MonsterInfo.m_dwKID || MonsterInfo::STATUE_AKHAN_LOADING2 == m_MonsterInfo.m_dwKID || MonsterInfo::POWER_STATUE_HUMAN_LOADING2 == m_MonsterInfo.m_dwKID || MonsterInfo::POWER_STATUE_AKHAN_LOADING2 == m_MonsterInfo.m_dwKID || MonsterInfo::INT_STATUE_HUMAN_LOADING2 == m_MonsterInfo.m_dwKID || MonsterInfo::INT_STATUE_AKHAN_LOADING2 == m_MonsterInfo.m_dwKID || MonsterInfo::EXP_STATUE_HUMAN_LOADING2 == m_MonsterInfo.m_dwKID || MonsterInfo::EXP_STATUE_AKHAN_LOADING2 == m_MonsterInfo.m_dwKID || MonsterInfo::WEALTH_STATUE_HUMAN_LOADING2 == m_MonsterInfo.m_dwKID || MonsterInfo::WEALTH_STATUE_AKHAN_LOADING2 == m_MonsterInfo.m_dwKID || MonsterInfo::LIFE_EXTRACT_HUMAN_LOADING2 == m_MonsterInfo.m_dwKID || MonsterInfo::LIFE_EXTRACT_AKHAN_LOADING2 == m_MonsterInfo.m_dwKID) { if (dwTick > m_dwLastTime + STATUE_LOADING_TIME) { Dead(NULL); return; } } else if (MonsterInfo::BG_STATUE_HUMAN_LOADING1 == m_MonsterInfo.m_dwKID || MonsterInfo::BG_STATUE_AKHAN_LOADING1 == m_MonsterInfo.m_dwKID || // 2·¹º§ MonsterInfo::BG_STATUE_HUMAN_LOADING2 == m_MonsterInfo.m_dwKID || MonsterInfo::BG_STATUE_AKHAN_LOADING2 == m_MonsterInfo.m_dwKID) { if (dwTick > m_dwLastTime + BG_STATUE_LOADING_TIME) { Dead(NULL); return; } } m_lCurrentFrame = UPDATE_INFO_CYCLE; } void CStatue::AttackBehavior(unsigned long dwTick) { m_lpTarget = m_Threat.GetTarget(); if (NULL == m_lpTarget || m_wDefaultSearchRange < m_CurrentPos.GetDistance(m_lpTarget->GetCurrentPos())) { CancelTarget(); } else if (m_lpTarget && true == m_lpTarget->GetEnchantInfo().GetFlag(Skill::SpellID::Hide)) { CancelTarget(); } NormalBehavior(dwTick); } void CStatue::ReturnBehavior(unsigned long dwTick) { m_nCurrentState = CFSM::GetInstance().StateTransition(m_nCurrentState, INPUT_ID_ARRIVAL_SITE); NormalBehavior(dwTick); } void CStatue::DeadBehavior(unsigned long dwTick) { // ±¸Á¶¹°Àº Á×Àº ÈÄ ÀÚµ¿À¸·Î ¸®½ºÆùµÇÁö ¾Ê´Â´Ù. ¸µÅ©µÈ ´Ù¸¥ ±¸Á¶¹°¿¡ ÀÇÇØ ¸®½ºÆù. } // ------------------------------------------------------------------------------------- // ¼öÁý ¸ó½ºÅÍ void CGatherMonster::NormalBehavior(unsigned long dwTick) { return; } void CGatherMonster::AttackBehavior(unsigned long dwTick) { m_lpTarget = m_Threat.GetTarget(); if (NULL != m_lpTarget) { // ÆÄƼÀÇ Å¸°ÙÀ¸·Î Áý¾î ³Ö´Â´Ù. CMonsterParty* lpParty = reinterpret_cast(GetParty()); if (NULL != lpParty) { // ·¹º§Â÷À̰¡ ³Ê¹« ³ª¸é ÆÄƼÀÇ Å¸°ÙÀ¸·Î Áý¾î³ÖÁö ¾Ê´Â´Ù. if (lpParty->GetHighestLevel() + CMonsterParty::ERROR_OF_LEVEL_GAP > m_lpTarget->GetStatus().m_nLevel) { // set ¿¡¼­ ¾ø¾îÁö´Â °ÍÀº CancelTarget ¿¡¼­ ó¸®ÇÑ´Ù. lpParty->GetPartyTargetSet().insert(m_lpTarget->GetCID()); return; } } } CancelTarget(true); } void CGatherMonster::ReturnBehavior(unsigned long dwTick) { m_nCurrentState = CFSM::GetInstance().StateTransition(m_nCurrentState, INPUT_ID_ARRIVAL_SITE); } // ------------------------------------------------------------------------------------- // ¿ÀºêÁ§Æ® ¸ó½ºÅÍ (²É, ³ª¹«, ¹ö¼¸·ù) void CObjectMonster::NormalBehavior(unsigned long dwTick) { return; } void CObjectMonster::AttackBehavior(unsigned long dwTick) { m_lpTarget = m_Threat.GetTarget(); if (NULL != m_lpTarget) { // ÆÄƼÀÇ Å¸°ÙÀ¸·Î Áý¾î ³Ö´Â´Ù. CMonsterParty* lpParty = reinterpret_cast(GetParty()); if (NULL != lpParty) { // ·¹º§Â÷À̰¡ ³Ê¹« ³ª¸é ÆÄƼÀÇ Å¸°ÙÀ¸·Î Áý¾î³ÖÁö ¾Ê´Â´Ù. if (lpParty->GetHighestLevel() + CMonsterParty::ERROR_OF_LEVEL_GAP > m_lpTarget->GetStatus().m_nLevel) { // set ¿¡¼­ ¾ø¾îÁö´Â °ÍÀº CancelTarget ¿¡¼­ ó¸®ÇÑ´Ù. lpParty->GetPartyTargetSet().insert(m_lpTarget->GetCID()); return; } } } CancelTarget(true); } void CObjectMonster::ReturnBehavior(unsigned long dwTick) { m_nCurrentState = CFSM::GetInstance().StateTransition(m_nCurrentState, INPUT_ID_ARRIVAL_SITE); } //--------------------------------------------------------------------------------------- // ÆÐÅÏ ¸ó½ºÅÍ void CSkillMonster::NormalBehavior(unsigned long dwTick) { CMonster::NormalBehavior(dwTick); // Chant ½ºÅ³ »ç¿ëÀ» ²ö´Ù. if (GetPattern() == MonsterInfo::PATTERN_BOSS || GetPattern() == MonsterInfo::PATTERN_NAMED || GetPattern() == MonsterInfo::PATTERN_CHIEF) { m_SpellMgr.GetCastingInfo().DisableChant(); } } void CSkillMonster::AttackBehavior(unsigned long dwTick) { PERFORMANCE_CHECK(FunctionTimingCheck) // ¸¶¹ý ij½ºÆÃ ÁßÀ϶§´Â.. ¾Æ¹«·± ´Ù¸¥ ÇൿÀ» ÇØ¼­´Â ¾ÈµÈ´Ù. if (true == m_bCasting) { CastingAttackAction(); return; } m_lpTarget = m_Threat.GetTarget(); if (NULL == m_lpTarget || MonsterInfo::PATTERN_BG == m_MonsterInfo.m_cSkillPattern) { CancelTarget(); return; } else if (m_lpTarget && true == m_lpTarget->GetEnchantInfo().GetFlag(Skill::SpellID::Hide)) { CancelTarget(); return; } // º´±â¿¡ ž½ÂÇÑ Ä³¸¯ÅÍ´Â ¶§¸®Áö ¾Ê´Â´Ù. if (Creature::CT_PC == Creature::GetCreatureType(m_lpTarget->GetCID())) { CCharacter* lpTargetChar = reinterpret_cast(m_lpTarget); if (lpTargetChar->IsRideArms()) { CancelTarget(); return; } } const float fDX = m_lpTarget->GetCurrentPos().m_fPointX - GetCurrentPos().m_fPointX; const float fDZ = m_lpTarget->GetCurrentPos().m_fPointZ - GetCurrentPos().m_fPointZ; const float fDistance = sqrtf((fDX * fDX) + (fDZ * fDZ)); if (((fDistance > m_wSearchRange) && false == m_bLongRangeAttacked) || (0 == m_lpTarget->GetStatus().m_nNowHP)) { CancelTarget(); return; } // ÆÄƼÀÇ Å¸°ÙÀ¸·Î Áý¾î ³Ö´Â´Ù. CMonsterParty* lpParty = reinterpret_cast(GetParty()); if (NULL != lpParty) { // ·¹º§Â÷À̰¡ ³Ê¹« ³ª¸é ÆÄƼÀÇ Å¸°ÙÀ¸·Î Áý¾î³ÖÁö ¾Ê´Â´Ù. if (lpParty->GetHighestLevel() + CMonsterParty::ERROR_OF_LEVEL_GAP > m_lpTarget->GetStatus().m_nLevel) { lpParty->GetPartyTargetSet().insert(m_lpTarget->GetCID()); // set ¿¡¼­ ¾ø¾îÁö´Â °ÍÀº CancelTarget ¿¡¼­ ó¸®ÇÑ´Ù. } else if (GetPattern() == MonsterInfo::PATTERN_BOSS || GetPattern() == MonsterInfo::PATTERN_NAMED || GetPattern() == MonsterInfo::PATTERN_CHIEF) { lpParty->GetPartyTargetSet().insert(m_lpTarget->GetCID()); // set ¿¡¼­ ¾ø¾îÁö´Â °ÍÀº CancelTarget ¿¡¼­ ó¸®ÇÑ´Ù. } } const float fAttackRange = m_MonsterInfo.m_wAttackRange / 100.0f; if (fDistance > fAttackRange && 0 >= m_lCurrentFrame) { // °ø°Ý ¹üÀ§ ¹ÛÀÌ´Ù. if (true == SkillAttack()) // ½ºÅ³ °ø°ÝÀ» »ç¿ëÇϴ°¡ üũ { SkillAttackAction(); } else { m_MotionInfo.m_wAction = MonsterInfo::Z3D_CA_WALK; // ÀÏ´Ü °È±â·Î ¼¼ÆÃ GetMotion(m_MotionInfo.m_wAction, m_MotionInfo); // °È±â ¸ð¼Ç Á¤º¸¸¦ ¾ò¾î¿Â´Ù. // ¸ó½ºÅͰ¡ À̵¿ °ø°ÝÀ» ÇÒ¸¸ÇÑ °Å¸®Àΰ¡ üũ if (fDistance < fAttackRange + m_MotionInfo.m_fVelocity) { // edith 2009.08.06 °ø°Ý½Ã °É¾î¼­ °ø°ÝÀ» ¾ø¾Ø´Ù. // ´Þ·Á°£´Ù RunAction(fDistance, m_lpTarget->GetCurrentPos().m_fPointX, m_lpTarget->GetCurrentPos().m_fPointZ); // °É¾î°¡¸é¼­ °ø°ÝÇÑ´Ù. // WalkAttackAction(fDistance - fAttackRange + 0.1f); // ³» Ȱµ¿±¸¿ªÀ» ¹þ¾î³ªµû. µ¹¾Æ°¡ÀÚ~! if (true == m_MonsterInfo.m_bReturnPosition && true == IsReturn()) { m_wSearchRange = OutsideSearchRange; CancelTarget(); } } else { // ´Þ·Á°£´Ù RunAction(fDistance, m_lpTarget->GetCurrentPos().m_fPointX, m_lpTarget->GetCurrentPos().m_fPointZ); // ³» Ȱµ¿±¸¿ªÀ» ¹þ¾î³ªµû. µ¹¾Æ°¡ÀÚ~! if (true == m_MonsterInfo.m_bReturnPosition && true == IsReturn()) { m_wSearchRange = OutsideSearchRange; CancelTarget(); } } } if (false == m_bAttacking) { m_lCurrentFrame = m_MotionInfo.m_dwFrame; } } else { // °ø°Ý ¹üÀ§ ¾ÈÀÌ´Ù. if (false == m_bAttacking) { if (true == SkillAttack()) // ½ºÅ³ °ø°ÝÀ» »ç¿ëÇϴ°¡ üũ { SkillAttackAction(); } else { AttackAction(); } } } } void CMageMonster::AttackBehavior(unsigned long dwTick) { PERFORMANCE_CHECK(FunctionTimingCheck) // ÀÏÁ¤ °Å¸®¸¦ À¯ÁöÇϸ鼭 ¸¶¹ý °ø°ÝÀ» »ç¿ë if (GetParty() == NULL) CSkillMonster::AttackBehavior(dwTick); else { // ¸¶¹ý ij½ºÆÃ ÁßÀ϶§´Â.. ¾Æ¹«·± ´Ù¸¥ ÇൿÀ» ÇØ¼­´Â ¾ÈµÈ´Ù. if (true == m_bCasting) { CastingAttackAction(); return; } m_lpTarget = m_Threat.GetTarget(); if (NULL == m_lpTarget) { CancelTarget(); return; } else if (m_lpTarget && true == m_lpTarget->GetEnchantInfo().GetFlag(Skill::SpellID::Hide)) { CancelTarget(); return; } // º´±â¿¡ ž½ÂÇÑ Ä³¸¯ÅÍ´Â ¶§¸®Áö ¾Ê´Â´Ù. if (Creature::CT_PC == Creature::GetCreatureType(m_lpTarget->GetCID())) { CCharacter* lpTargetChar = reinterpret_cast(m_lpTarget); if (lpTargetChar->IsRideArms()) { CancelTarget(); return; } } const float fDX = m_lpTarget->GetCurrentPos().m_fPointX - GetCurrentPos().m_fPointX; const float fDZ = m_lpTarget->GetCurrentPos().m_fPointZ - GetCurrentPos().m_fPointZ; const float fDistance = sqrtf((fDX * fDX) + (fDZ * fDZ)); if (((fDistance > m_wSearchRange) && false == m_bLongRangeAttacked) || (0 == m_lpTarget->GetStatus().m_nNowHP)) { CancelTarget(); return; } // ÆÄƼÀÇ Å¸°ÙÀ¸·Î Áý¾î ³Ö´Â´Ù. CMonsterParty* lpParty = reinterpret_cast(GetParty()); if (NULL != lpParty) { // ·¹º§Â÷À̰¡ ³Ê¹« ³ª¸é ÆÄƼÀÇ Å¸°ÙÀ¸·Î Áý¾î³ÖÁö ¾Ê´Â´Ù. if (lpParty->GetHighestLevel() + CMonsterParty::ERROR_OF_LEVEL_GAP > m_lpTarget->GetStatus().m_nLevel) { lpParty->GetPartyTargetSet().insert(m_lpTarget->GetCID()); // set ¿¡¼­ ¾ø¾îÁö´Â °ÍÀº CancelTarget ¿¡¼­ ó¸®ÇÑ´Ù. } } // °Å¸® üũ float fToMemberX, fToMemberZ, fToTargetX, fToTargetZ; float fDstX, fDstZ; fToTargetX = m_lpTarget->GetCurrentPos().m_fPointX - GetCurrentPos().m_fPointX; fToTargetZ = m_lpTarget->GetCurrentPos().m_fPointZ - GetCurrentPos().m_fPointZ; CAggresiveCreature* lpHiLVMember = FindHighestLVMember(); if (lpHiLVMember) { fToMemberX = lpHiLVMember->GetCurrentPos().m_fPointX - GetCurrentPos().m_fPointX; fToMemberZ = lpHiLVMember->GetCurrentPos().m_fPointZ - GetCurrentPos().m_fPointZ; } else { fToMemberX = GetCurrentPos().m_fPointX; fToMemberZ = GetCurrentPos().m_fPointZ; } if (0 >= m_lCurrentFrame) { if (fDistance < NEAR_DIST_TO_TARGET) { // ³Ê¹« °¡±î¿ì¸é µµ¸Á°£´Ù. fDstX = GetCurrentPos().m_fPointX - (fToMemberX + fToTargetX) / 2; fDstZ = GetCurrentPos().m_fPointZ - (fToMemberZ + fToTargetZ) / 2; // ´Þ·Á°£´Ù RunAction(fDistance, fDstX, fDstZ); // ³» Ȱµ¿±¸¿ªÀ» ¹þ¾î³ªµû. µ¹¾Æ°¡ÀÚ~! if (true == m_MonsterInfo.m_bReturnPosition && true == IsReturn()) { m_wSearchRange = OutsideSearchRange; CancelTarget(); } } else if (fDistance > FAR_DIST_TO_TARGET) { fDstX = GetCurrentPos().m_fPointX + (fToMemberX + fToTargetX) / 2; fDstZ = GetCurrentPos().m_fPointZ + (fToMemberZ + fToTargetZ) / 2; // ´Þ·Á°£´Ù RunAction(fDistance, fDstX, fDstZ); // ³» Ȱµ¿±¸¿ªÀ» ¹þ¾î³ªµû. µ¹¾Æ°¡ÀÚ~! if (true == m_MonsterInfo.m_bReturnPosition && true == IsReturn()) { m_wSearchRange = OutsideSearchRange; CancelTarget(); } } else { // ½ºÅ³ °ø°ÝÀ» »ç¿ëÇϴ°¡ üũ if (false == m_bAttacking && true == SkillAttack()) { SkillAttackAction(); } } if (false == m_bAttacking) { m_lCurrentFrame = m_MotionInfo.m_dwFrame; } } } } void CAcolyteMonster::AttackBehavior(unsigned long dwTick) { PERFORMANCE_CHECK(FunctionTimingCheck) // ÀÏÁ¤ °Å¸®¸¦ À¯ÁöÇϸ鼭 ¸¶¹ý °ø°ÝÀ» »ç¿ë if (GetParty() == NULL) CSkillMonster::AttackBehavior(dwTick); else { // ¸¶¹ý ij½ºÆÃ ÁßÀ϶§´Â.. ¾Æ¹«·± ´Ù¸¥ ÇൿÀ» ÇØ¼­´Â ¾ÈµÈ´Ù. if (true == m_bCasting) { CastingAttackAction(); return; } m_lpTarget = m_Threat.GetTarget(); if (NULL == m_lpTarget) { CancelTarget(); return; } else if (m_lpTarget && true == m_lpTarget->GetEnchantInfo().GetFlag(Skill::SpellID::Hide)) { CancelTarget(); return; } // º´±â¿¡ ž½ÂÇÑ Ä³¸¯ÅÍ´Â ¶§¸®Áö ¾Ê´Â´Ù. if (Creature::CT_PC == Creature::GetCreatureType(m_lpTarget->GetCID())) { CCharacter* lpTargetChar = reinterpret_cast(m_lpTarget); if (lpTargetChar->IsRideArms()) { CancelTarget(); return; } } const float fDX = m_lpTarget->GetCurrentPos().m_fPointX - GetCurrentPos().m_fPointX; const float fDZ = m_lpTarget->GetCurrentPos().m_fPointZ - GetCurrentPos().m_fPointZ; const float fDistance = sqrtf((fDX * fDX) + (fDZ * fDZ)); if (((fDistance > m_wSearchRange) && false == m_bLongRangeAttacked) || (0 == m_lpTarget->GetStatus().m_nNowHP)) { CancelTarget(); return; } // ÆÄƼÀÇ Å¸°ÙÀ¸·Î Áý¾î ³Ö´Â´Ù. CMonsterParty* lpParty = reinterpret_cast(GetParty()); if (NULL != lpParty) { // ·¹º§Â÷À̰¡ ³Ê¹« ³ª¸é ÆÄƼÀÇ Å¸°ÙÀ¸·Î Áý¾î³ÖÁö ¾Ê´Â´Ù. if (lpParty->GetHighestLevel() + CMonsterParty::ERROR_OF_LEVEL_GAP > m_lpTarget->GetStatus().m_nLevel) { lpParty->GetPartyTargetSet().insert(m_lpTarget->GetCID()); // set ¿¡¼­ ¾ø¾îÁö´Â °ÍÀº CancelTarget ¿¡¼­ ó¸®ÇÑ´Ù. } } // °Å¸® üũ float fToMemberX, fToMemberZ, fToTargetX, fToTargetZ; float fDstX, fDstZ; fToTargetX = m_lpTarget->GetCurrentPos().m_fPointX - GetCurrentPos().m_fPointX; fToTargetZ = m_lpTarget->GetCurrentPos().m_fPointZ - GetCurrentPos().m_fPointZ; CAggresiveCreature* lpHiLVMember = FindHighestLVMember(); if (lpHiLVMember) { fToMemberX = lpHiLVMember->GetCurrentPos().m_fPointX - GetCurrentPos().m_fPointX; fToMemberZ = lpHiLVMember->GetCurrentPos().m_fPointZ - GetCurrentPos().m_fPointZ; } else { fToMemberX = GetCurrentPos().m_fPointX; fToMemberZ = GetCurrentPos().m_fPointZ; } if (0 >= m_lCurrentFrame) { if (fDistance < NEAR_DIST_TO_TARGET) { // ³Ê¹« °¡±î¿ì¸é µµ¸Á°£´Ù. fDstX = GetCurrentPos().m_fPointX - (fToMemberX + fToTargetX) / 2; fDstZ = GetCurrentPos().m_fPointZ - (fToMemberZ + fToTargetZ) / 2; // ´Þ·Á°£´Ù RunAction(fDistance, fDstX, fDstZ); // ³» Ȱµ¿±¸¿ªÀ» ¹þ¾î³ªµû. µ¹¾Æ°¡ÀÚ~! if (true == m_MonsterInfo.m_bReturnPosition && true == IsReturn()) { m_wSearchRange = OutsideSearchRange; CancelTarget(); } } else if (fDistance > FAR_DIST_TO_TARGET) { fDstX = GetCurrentPos().m_fPointX + (fToMemberX + fToTargetX) / 2; fDstZ = GetCurrentPos().m_fPointZ + (fToMemberZ + fToTargetZ) / 2; // ´Þ·Á°£´Ù RunAction(fDistance, fDstX, fDstZ); // ³» Ȱµ¿±¸¿ªÀ» ¹þ¾î³ªµû. µ¹¾Æ°¡ÀÚ~! if (true == m_MonsterInfo.m_bReturnPosition && true == IsReturn()) { m_wSearchRange = OutsideSearchRange; CancelTarget(); } } else { // ½ºÅ³ °ø°ÝÀ» »ç¿ëÇϴ°¡ üũ if (false == m_bAttacking && true == SkillAttack()) { SkillAttackAction(); } } if (false == m_bAttacking) { m_lCurrentFrame = m_MotionInfo.m_dwFrame; } } } } void CMonster::AttackAction() { m_MotionInfo.m_fDirection = CalcDir2D(GetCurrentPos().m_fPointX, GetCurrentPos().m_fPointZ, m_lpTarget->GetCurrentPos().m_fPointX, m_lpTarget->GetCurrentPos().m_fPointZ); if (false == MultiAttack()) { ERRLOG1(g_Log, "CID:0x%08x ¸ó½ºÅͰ¡ °ø°ÝÀ» ½ÇÆÐÇÏ¿´½À´Ï´Ù.", m_dwCID); } m_bAttacking = true; m_bLongRangeAttacked = false; GetMotion(MonsterInfo::Z3D_CA_ATTACK, m_MotionInfo); m_lCurrentFrame = m_MotionInfo.m_dwFrame; m_MotionInfo.m_fVelocity = 0; // edith 2009.08.06 ½ºÅ³ °ø°Ý½Ã À̵¿ÇÏÁö ¾Ê°Ô Çϱâ ms_AttackBehaviorSendCount += SendMove(1); m_nLeaveMovingNum = 0; } void CMonster::WalkAttackAction(float fVelocity) { // °ø°Ý ¹üÀ§ ¹ÛÀÌ´Ù. m_MotionInfo.m_wAction = MonsterInfo::Z3D_CA_WALK; // ÀÏ´Ü °È±â·Î ¼¼ÆÃ GetMotion(m_MotionInfo.m_wAction, m_MotionInfo); // °È±â ¸ð¼Ç Á¤º¸¸¦ ¾ò¾î¿Â´Ù. // °É¾î°£´Ù. m_MotionInfo.m_fDirection = CalcDir2D(GetCurrentPos().m_fPointX, GetCurrentPos().m_fPointZ, m_lpTarget->GetCurrentPos().m_fPointX, m_lpTarget->GetCurrentPos().m_fPointZ); // Àû´çÈ÷ °É¾î°¡¼­... // m_MotionInfo.m_fVelocity = fDistance - fAttackRange + 0.1f; m_MotionInfo.m_fVelocity = fVelocity; // °ø°Ý~!! if (false == MultiAttack()) { ERRLOG1(g_Log, "CID:0x%08x ¸ó½ºÅͰ¡ °ø°ÝÀ» ½ÇÆÐÇÏ¿´½À´Ï´Ù.", m_dwCID); } m_bAttacking = true; m_bLongRangeAttacked = false; ms_AttackBehaviorSendCount += SendMove(RUN_ANI_LIMIT_MAX); MoveTo(CalculateCoor(), false); m_nLeaveMovingNum = 0; GetMotion(MonsterInfo::Z3D_CA_ATTACK, m_MotionInfo); m_lCurrentFrame = m_MotionInfo.m_dwFrame; } void CMonster::RunAction(float fDistance, float fDstX, float fDstZ) { // ´Þ·Á°£´Ù m_MotionInfo.m_wAction = MonsterInfo::Z3D_CA_RUN; GetMotion(m_MotionInfo.m_wAction, m_MotionInfo); float fNewDirection = CalcDir2D(GetCurrentPos().m_fPointX, GetCurrentPos().m_fPointZ, fDstX, fDstZ); if (m_nLeaveMovingNum <= 0 || (m_MotionInfo.m_fDirection - fNewDirection) > 1.0f || (fNewDirection - m_MotionInfo.m_fDirection) > 1.0f) { m_MotionInfo.m_fDirection = fNewDirection; short nAniNum = static_cast(fDistance / m_MotionInfo.m_fVelocity); if(nAniNum <= 0) nAniNum = RUN_ANI_LIMIT_MIN; // edith 2008.01.23 ¸ó½ºÅͰ¡ °ø°ÝÀ» ½ÃÀÛÇßÀ»´ë À̵¿ÇÒ¼öÀÖ´Â ·çÇÁ nAniNum = (nAniNum > RUN_ANI_LIMIT_MAX) ? RUN_ANI_LIMIT_MAX : nAniNum;//RUN_ANI_LIMIT_MIN; ms_AttackBehaviorSendCount += SendMove(nAniNum); } --m_nLeaveMovingNum; if (F_CELL_CANNOTCHANGE == MoveTo(CalculateCoor(), false)) { ms_AttackBehaviorSendCount += SendMove(RUN_ANI_LIMIT_MIN); m_nLeaveMovingNum = 0; } } bool CMonster::IsReturn() { const float fOriginalDX = m_OriginalPosition.m_fPointX - GetCurrentPos().m_fPointX; const float fOriginalDZ = m_OriginalPosition.m_fPointZ - GetCurrentPos().m_fPointZ; const float fOriginalDistance = (fOriginalDX * fOriginalDX) + (fOriginalDZ * fOriginalDZ); const int nTempReturnRange = (true == m_bLongRangeAttacked) ? (LongRange + Math::Random::ComplexRandom(6) - 2) : (ReturnRange + Math::Random::ComplexRandom(6) - 2); if (fOriginalDistance > (nTempReturnRange * nTempReturnRange)) return true; return false; } void CSkillMonster::CastingAttackAction() { // ij½ºÆÃ ¾Ö´Ï¸ÞÀÌ¼Ç ÁßÀ̶ó¸é... if (m_lCurrentFrame > 0) { CAggresiveCreature* pTarget = CCreatureManager::GetInstance().GetAggresiveCreature(m_dwTargetCID); if (NULL == pTarget || pTarget->GetMapIndex() != GetMapIndex() || true == pTarget->GetEnchantInfo().GetFlag(Skill::SpellID::Hide)) { m_dwTargetCID = 0; m_lpTarget = NULL; m_bCasting = false; CancelTarget(); return; } // º´±â¿¡ ž½ÂÇÑ Ä³¸¯ÅÍ´Â ¶§¸®Áö ¾Ê´Â´Ù. if (Creature::CT_PC == Creature::GetCreatureType(pTarget->GetCID())) { CCharacter* lpTargetChar = reinterpret_cast(pTarget); if (lpTargetChar->IsRideArms()) { m_dwTargetCID = 0; m_lpTarget = NULL; m_bCasting = false; CancelTarget(); return; } } return; } // Ä¡ÇÁ, ¸ÞÀÌÁö, ¾îÄݶóÀÌÆ®´Â ij½ºÆÃ µ¿ÀÛÀ» ¿À·¡ ÃëÇÑ´Ù. if (GetPattern() == MonsterInfo::PATTERN_CHIEF || GetPattern() == MonsterInfo::PATTERN_MAGE || GetPattern() == MonsterInfo::PATTERN_ACOLYTE) { if (m_nCastingCount > 0) { if (m_lpTarget) { m_MotionInfo.m_fDirection = CalcDir2D(GetCurrentPos().m_fPointX, GetCurrentPos().m_fPointZ, m_lpTarget->GetCurrentPos().m_fPointX, m_lpTarget->GetCurrentPos().m_fPointZ); GetMotion(MonsterInfo::Z3D_CA_CASTING, m_MotionInfo); m_lCurrentFrame = m_MotionInfo.m_dwFrame; m_bCasting = true; m_MotionInfo.m_fVelocity = 0.0f; // edith 2009.08.06 ½ºÅ³ °ø°Ý½Ã À̵¿ÇÏÁö ¾Ê°Ô Çϱâ ms_AttackBehaviorSendCount += SendMove(1); m_nLeaveMovingNum = 0; --m_nCastingCount; } else { m_dwTargetCID = 0; m_bCasting = false; m_nCastingCount = 0; CancelTarget(); } return; } } // ij½ºÆÃÀÌ ³¡³­ÈÄ ½ºÅ³ »ç¿ë UseCastedSkill(); m_bCasting = false; m_bAttacking = true; m_bLongRangeAttacked = false; m_nCastingCount = 0; GetMotion(MonsterInfo::Z3D_CA_ATTACK, m_MotionInfo); m_lCurrentFrame = m_MotionInfo.m_dwFrame; } void CSkillMonster::SkillAttackAction() { m_bAttacking = true; m_MotionInfo.m_fDirection = CalcDir2D(GetCurrentPos().m_fPointX, GetCurrentPos().m_fPointZ, m_lpTarget->GetCurrentPos().m_fPointX, m_lpTarget->GetCurrentPos().m_fPointZ); // ij½ºÆÃ ŸÀÔÀÇ ½ºÅ³À̶ó¸é ij½ºÆÃ ¾×¼ÇÀ¸·Î º¯°æ if (true == m_bCasting) { GetMotion(MonsterInfo::Z3D_CA_CASTING, m_MotionInfo); m_lCurrentFrame = m_MotionInfo.m_dwFrame; m_MotionInfo.m_fVelocity = 0.0f; // edith 2009.08.06 ½ºÅ³ °ø°Ý½Ã À̵¿ÇÏÁö ¾Ê°Ô Çϱâ ms_AttackBehaviorSendCount += SendMove(1); m_nLeaveMovingNum = 0; m_nCastingCount = m_attackType.m_cSkillLockCount; } else { GetMotion(MonsterInfo::Z3D_CA_ATTACK, m_MotionInfo); m_lCurrentFrame = m_MotionInfo.m_dwFrame; m_MotionInfo.m_fVelocity = 0.0f; // edith 2009.08.06 ½ºÅ³ °ø°Ý½Ã À̵¿ÇÏÁö ¾Ê°Ô Çϱâ ms_AttackBehaviorSendCount += SendMove(1); m_nLeaveMovingNum = 0; m_nCastingCount = 0; } }