#include "stdafx.h" #include "ReturnState.h" #include #include "AIParamParser.h" #include "PublicMath.h" #include #include "GameField.h" #include "../MovingPlanner.h" #include "BattleRecord.h" #include "StatusManager.h" #include "Monster.h" #include "TargetManager.h" ReturnState::ReturnState() { } ReturnState::~ReturnState() { } void ReturnState::Init() { } void ReturnState::SetNPC(NPC* pNpc) { m_pMonster = DOWNCASTER_SELECT(pNpc); if (m_pMonster == NULL || pNpc->IsEqualObjectKind(MONSTER_OBJECT) == false) { SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"]|Unexpected type %08X", pNpc->GetObjectType()); __debugbreak(); } State::SetNPC(pNpc); } void ReturnState::OnEnter(LPARAM param1, LPARAM param2, LPARAM param3) { State::OnEnter(param1, param2, param3); // (CHANGES) (100206) (WAVERIX) PCC_CONTINUING_NPC_UPDATE Ãß°¡¿¡ µû¸¥ »óÅ ¹Ý¿µ const sPOLICY_CHARACTER& CharPolicyment = m_pNPC->Policyment; m_pNPC->ChangePolicyPostEnterField(CharPolicyment.PCC_CONTINUING_NPC_UPDATE, CharPolicyment.PCC_DISABLE_ALL, NULL); if (m_pMonster->MoveAndBroadcast(&m_pMonster->GetRegenPos(), CMS_RUN)) { m_bRegenPosSelected = true; } else { m_bRegenPosSelected = false; } m_pMonster->GetStatusManager()->AllocStatus(eCHAR_STATE_ETC_RETURNING); // ¸®ÅÏ»óÅ¿¡¼­´Â ±âÁ¸ÀÇ BattleRecord Á¤º¸¸¦ ÃʱâÈ­ÇÑ´Ù. m_pMonster->GetTargetManager()->ClearBattleRecord(); m_TrackTimer.SetTimer(m_TrackTimer.eStaticTimer_Track, m_pAITypeInfo->m_wTRACK_PERIOD); // (CHANGES) (091231) (WAVERIX) return command by leader control if (m_pMonster->IsLeader()) { AI_MSG_CHANGETORETURNSTATE returnMsg; m_pNPC->SendAIMessageToGroupExceptMe(&returnMsg, sizeof(returnMsg), (WORD)dRandom(AIParamParser::AICommonInfo.m_wGROUP_AIMESSAGE_MIN_DELAY, AIParamParser::AICommonInfo.m_wGROUP_AIMESSAGE_MAX_DELAY)); } } void ReturnState::OnExit() { State::OnExit(); // ¿Í¿ìó·³ HP full·Î ä¿öÁÖ´Â °Íµµ ÁÁÁö ¾ÊÀ»±î;; // ÀüÅõÁ¤º¸ ÃʱâÈ­ //m_pMonster->GetBattleRecord().Init(); m_pMonster->GetStatusManager()->Remove(eCHAR_STATE_ETC_RETURNING); // (CHANGES) (100206) (WAVERIX) PCC_CONTINUING_NPC_UPDATE Ãß°¡¿¡ µû¸¥ »óÅ ¹Ý¿µ const sPOLICY_CHARACTER& CharPolicyment = m_pNPC->Policyment; m_pNPC->ChangePolicyPostEnterField(CharPolicyment.PCC_DISABLE_ALL, CharPolicyment.PCC_CONTINUING_NPC_UPDATE, NULL); } BOOL ReturnState::OnUpdate(DWORD dwDeltaTick) { __UNUSED(dwDeltaTick); // À̵¿ÀÌ ³¡³ª¸é ´Ù½Ã RegenPos·Î ¿òÁ÷ÀδÙ. if (m_TrackTimer.IsExpired() && !m_pMonster->IsMoving()) { // ¸ñÀûÁö¿¡ µµ´ÞÇϸé Idle»óÅ·ΠÀüÀÌ if (m_bRegenPosSelected) { MSGSUB_SYNC_STOP_BRD msg; msg.m_dwObjectKey = m_pMonster->GetObjectKey(); msg.m_wvCurPos = *m_pMonster->GetPosPtr(); m_pMonster->SendPacketAroundForSync(&msg); m_pMonster->ChangeState(STATE_ID_IDLE); return true; } // ¸ñÀûÁö¿¡ µµ´ÞÇÒ ¶§±îÁö ´Ù½Ã À̵¿ else { DoReturn(); } } return true; } void ReturnState::DoReturn() { const WzVector& wvCurPos = *m_pMonster->GetPosPtr(); WzVector regen_pos = m_pMonster->GetRegenPos(); BOOLEAN need_change_regen_pos = false; BOOLEAN is_movable_cur_tile = true; // (CHANGES) (091229) (WAVERIX) ÀÚ±â ÀÚ½ÅÀÇ ÀûÀýÇÑ »óŸ¦ Æò°¡ÇÒ ÇÊ¿ä ÀÖ´Ù. // ¼±Çà Á¶°ÇÀ¸·Î ÃæºÐÇϹǷΠ¹Ì¸® °è»êÇØ µÐ´Ù. // track->return:change regeneration pos // track->attack is_movable_cur_tile = !!nsAI::PlanEventObject::AcceptableTarget(m_pMonster, 0, 0); // À̵¿ÇÒ °Å¸®¸¦ ±¸ÇÑ´Ù. const float MoveDistance = (float)dRandom(AIParamParser::AICommonInfo.m_fMIN_MOVE_DISTANCE, AIParamParser::AICommonInfo.m_fMAX_MOVE_DISTANCE); const WzVector& diff = regen_pos - wvCurPos; float fDistFromRegenPosSq = VectorLength2(&diff); WzVector wvDestPos; if (is_movable_cur_tile != false) { if ((MoveDistance * MoveDistance) >= fDistFromRegenPosSq) { wvDestPos = regen_pos; m_bRegenPosSelected = true; } else { WzVector wvNormal; // RegenPos¸¦ ÇâÇØ Á¶±Ý¾¿ ±æÃ£±âÇÑ´Ù. VectorNormalize(&wvNormal, &diff); // (CHANGES) (091229) (WAVERIX) remove z=0, Á» ´õ ³ôÀÌ °ËÁõÀÌ Á¤¹ÐÇØÁ³±â ¶§¹®¿¡... //wvNormal.z = 0; wvDestPos = wvCurPos + wvNormal * MoveDistance; } } else { // is_movable_cur_tile == false need_change_regen_pos = true; } if (is_movable_cur_tile != false) { // À̵¿°¡´É ¿©ºÎ¸¦ üũÈÄ ÆÐŶÀ» ³¯¸°´Ù. if (m_pMonster->MoveAndBroadcast(&wvDestPos, CMS_RUN) == false) { // À̵¿ÀÌ ½ÇÆÐÇϸé Á÷Á¢ ¸®Á¨ÁÂÇ¥·Î À̵¿Çغ»´Ù. if (m_pMonster->MoveAndBroadcast(®en_pos, CMS_RUN) == false) { need_change_regen_pos = true; } } } #ifdef _NA_008244_20150422_MODIFY_MONSTER_ESCAPE_SAFETY_ZONE if (need_change_regen_pos != false) { GameField* cur_field = m_pMonster->GetField(); // Çʵ尡 Á¸ÀçÇϰí, ÇöÀçÀ§Ä¡°¡ ¾ÈÀüÁö´ëÀ̸é ÅÚ·¹Æ÷Æ®¸¦ ½ÃÄѹö¸°´Ù if (cur_field != NULL) { cur_field->TeleportObject(m_pMonster, ®en_pos); m_pMonster->ChangeState(STATE_ID_IDLE); } else { // ±×·¡µµ ½ÇÆÐÇÏ¸é ¸®Á¨ÁÂÇ¥¸¦ ÇöÀç ÁÂÇ¥·Î ¼ÂÆÃÇØ ¹ö¸°´Ù! // m_pMonster->SetRegenPos(wvCurPos); m_pMonster->ChangeState(STATE_ID_IDLE); MSGSUB_SYNC_STOP_BRD msg; msg.m_dwObjectKey = m_pMonster->GetObjectKey(); msg.m_wvCurPos = wvCurPos; m_pMonster->SendPacketAroundForSync(&msg); } return; } #else if (need_change_regen_pos != false) { // ±×·¡µµ ½ÇÆÐÇÏ¸é ¸®Á¨ÁÂÇ¥¸¦ ÇöÀç ÁÂÇ¥·Î ¼ÂÆÃÇØ ¹ö¸°´Ù! // m_pMonster->SetRegenPos(wvCurPos); m_pMonster->ChangeState(STATE_ID_IDLE); MSGSUB_SYNC_STOP_BRD msg; msg.m_dwObjectKey = m_pMonster->GetObjectKey(); msg.m_wvCurPos = wvCurPos; m_pMonster->SendPacketAroundForSync(&msg); return; } #endif //_NA_008244_20150422_MODIFY_MONSTER_ESCAPE_SAFETY_ZONE m_TrackTimer.SetTimer(m_TrackTimer.eStaticTimer_Track, m_pAITypeInfo->m_wTRACK_PERIOD); }