BOOL TMonsterAIElement::ApplyElementAvoid(int iIndex, int iTargetIndex, TMonsterAIState * pAIState) { LPOBJ lpObj = &gObj[iIndex]; UTIL.SendCrywolfChattingMsg(iIndex, "Element-회피"); KANTURU_UTIL.SendKanturuChattingMsg(iIndex, "Element-회피"); BOOL bFindXY = MONSTER_UTIL.GetXYToEascape(lpObj); if ( bFindXY ) { MONSTER_UTIL.FindPathToMoveMonster(lpObj, lpObj->MTX, lpObj->MTY, 5, 1); } return FALSE; }
BOOL TMonsterAIElement::ApplyElementMove(int iIndex, int iTargetIndex, TMonsterAIState * pAIState) { LPOBJ lpObj = &gObj[iIndex]; UTIL.SendCrywolfChattingMsg(iIndex, "Element-이동"); KANTURU_UTIL.SendKanturuChattingMsg(iIndex, "Element-이동"); if ( lpObj->PathStartEnd ) return FALSE; BOOL bFindXY = FALSE; if ( pAIState->m_iTransitionType == 2 ) bFindXY = MONSTER_UTIL.GetXYToChase(lpObj); else bFindXY = MONSTER_UTIL.GetXYToPatrol(lpObj); if ( bFindXY ) MONSTER_UTIL.FindPathToMoveMonster(lpObj, lpObj->MTX, lpObj->MTY, 5, 1); return FALSE; }
void CDoppelganger::MoveProc(LPOBJ lpObj) { if(DOPPELGANGER_MAP_RANGE(lpObj->MapNumber) && lpObj->Type == OBJ_MONSTER){ for(int X=0; X < this->MonstersCount;X++){ if(this->CurrentMonster[X] == lpObj->m_Index){ lpObj->MTX = this->PosX[this->EventMap-65]; lpObj->MTY = this->PosY[this->EventMap-65]; MonsterAIUtil.FindPathToMoveMonster(lpObj,lpObj->MTX,lpObj->MTY,15,2); } } } }
BOOL TMonsterAIElement::ApplyElementGroupMove(int iIndex, int iTargetIndex, TMonsterAIState * pAIState) { LPOBJ lpObj = &gObj[iIndex]; UTIL.SendCrywolfChattingMsg(iIndex, "Element-그룹이동"); if ( lpObj->PathStartEnd ) return FALSE; BOOL bFindXY = FALSE; BOOL bFoundLeader = TRUE; int iLeaderIndex = -1; iLeaderIndex = TMonsterAIGroup::FindGroupLeader(lpObj->m_iGroupNumber); if ( iLeaderIndex == -1 || gObj[iLeaderIndex].Live == FALSE ) bFoundLeader = FALSE; if ( bFoundLeader && gObjCalDistance(lpObj, &gObj[iLeaderIndex]) > 6 ) { lpObj->TargetNumber = iLeaderIndex; bFindXY = MONSTER_UTIL.GetXYToChase(lpObj); } else if ( pAIState->m_iTransitionType == 2 ) { bFindXY = MONSTER_UTIL.GetXYToChase(lpObj); } else { bFindXY = MONSTER_UTIL.GetXYToPatrol(lpObj); } if ( bFindXY ) { if ( MONSTER_UTIL.FindPathToMoveMonster(lpObj, lpObj->MTX, lpObj->MTY, 5, TRUE) ) { } else { MONSTER_UTIL.GetXYToPatrol(lpObj); MONSTER_UTIL.FindPathToMoveMonster(lpObj, lpObj->MTX, lpObj->MTY, 5, TRUE); } } return FALSE; }
void TMonsterAI::MonsterMove(int iIndex) { LPOBJ lpObj = &gObj[iIndex]; if ( MONSTER_UTIL.CheckMovingCondition(lpObj) == FALSE ) { lpObj->PathCur = 0; lpObj->PathCount = 0; lpObj->PathStartEnd = 0; memset(lpObj->PathX, 0, sizeof(lpObj->PathX)); memset(lpObj->PathY, 0, sizeof(lpObj->PathY)); memset(lpObj->PathDir, 0, sizeof(lpObj->PathY)); //check this out return ; } if ( lpObj->PathCount != 0 ) { DWORD dwMoveTime = 0; DWORD dwDelayTime = 0; if ( lpObj->DelayLevel != 0 ) dwDelayTime = 300; else dwDelayTime = 0; lpObj->m_MoveSpeed = 300; if ( (lpObj->PathDir[lpObj->PathCur] % 2 ) == 0 ) dwMoveTime = (DWORD)((double)(lpObj->m_MoveSpeed + dwDelayTime) * 1.3); else dwMoveTime = lpObj->m_MoveSpeed + dwDelayTime; if ( (GetTickCount() - lpObj->PathTime) > dwMoveTime ) { if ( lpObj->PathCur < 15 ) { lpObj->X = lpObj->PathX[lpObj->PathCur]; lpObj->Y = lpObj->PathY[lpObj->PathCur]; lpObj->Dir = lpObj->PathDir[lpObj->PathCur]; lpObj->PathTime = GetTickCount(); lpObj->PathCur++; if ( lpObj->PathCur >= lpObj->PathCount ) { lpObj->PathCur = 0; lpObj->PathCount = 0; lpObj->PathStartEnd = 0; } } CreateFrustrum(lpObj->X, lpObj->Y, iIndex); } return; } lpObj->PathCur = 0; lpObj->PathCount = 0; lpObj->PathStartEnd = 0; memset(lpObj->PathX, 0, sizeof(lpObj->PathX)); memset(lpObj->PathY, 0, sizeof(lpObj->PathY)); memset(lpObj->PathDir, 0, sizeof(lpObj->PathY)); //check this out }
BOOL TMonsterAIElement::ApplyElementMoveTarget(int iIndex, int iTargetIndex, TMonsterAIState * pAIState) { LPOBJ lpObj = &gObj[iIndex]; UTIL.SendCrywolfChattingMsg(iIndex, "Element-MoveTarget"); #if (__CUSTOM__ == 0) KANTURU_UTIL.SendKanturuChattingMsg(iIndex, "Element-타겟이동"); #endif if ( lpObj->PathStartEnd ) return FALSE; if ( lpObj->X == this->m_iX && lpObj->Y == this->m_iY ) { this->ApplyElementMove(iIndex, iTargetIndex, pAIState); return FALSE; } BOOL bFindXY = TRUE; int iTargetX = this->m_iX; int iTargetY = this->m_iY; int iTargetDistance = (int)sqrt(double(((lpObj->X - iTargetX)*(lpObj->X - iTargetX))+ ((lpObj->Y - iTargetY)*(lpObj->Y - iTargetY)))); if ( TMonsterAIElement::s_MonsterAIMovePath[lpObj->MapNumber].m_bDataLoad ) { if ( iTargetDistance > 10 ) { int iMinCost = 1000000; int iMidX = -1; int iMidY = -1; int iSpotNum = -1; for ( int i=0;i<MAX_MONSTER_AI_MOVE_PATH;i++) { TMonsterAIMovePathInfo & PathInfo = TMonsterAIElement::s_MonsterAIMovePath[lpObj->MapNumber].m_MovePathInfo[i]; float fDistX = (float)(lpObj->X - PathInfo.m_iPathX); float fDistY = (float)(lpObj->Y - PathInfo.m_iPathY); int iPathSpotDist = (int)sqrt( (fDistX*fDistX) + (fDistY*fDistY) ); if ( iPathSpotDist < 20 ) { fDistX = (float)(iTargetX - PathInfo.m_iPathX); fDistY = (float)(iTargetY - PathInfo.m_iPathY); int iMidDist = (int)sqrt( (fDistX*fDistX) + (fDistY*fDistY) ); if ( iMinCost > iMidDist ) { if ( iMidDist ) { iMinCost = iMidDist; iMidX = PathInfo.m_iPathX; iMidY = PathInfo.m_iPathY; iSpotNum = i; } } } } if ( iMinCost != 1000000 ) { iTargetX = iMidX; iTargetY = iMidY; } } } if ( bFindXY ) { if ( MONSTER_UTIL.FindPathToMoveMonster(lpObj, iTargetX, iTargetY, 7, FALSE) ) lpObj->PathStartEnd = 1; else lpObj->PathStartEnd = 0; } return FALSE; }
TMonsterAIState * TMonsterAIAutomata::RunAutomata(int iIndex) { LPOBJ lpObj = &gObj[iIndex]; if ( MAX_AI_STATE_RANGE(lpObj->m_iCurrentAIState) == FALSE ) return NULL; LPOBJ lpTargetObj = NULL; int iMaxAgro = -1; int iTargetIndex = lpObj->m_Agro.GetMaxAgroUserIndex(lpObj->m_Index); // Search The user with Max Agro to make its enemy if ( iTargetIndex != -1 ) { lpTargetObj = &gObj[iTargetIndex]; if ( MONSTER_UTIL.FindMonViewportObj(lpObj->m_Index, lpTargetObj->m_Index) ) { iMaxAgro = lpObj->m_Agro.GetAgro(iTargetIndex); lpObj->TargetNumber = iTargetIndex; } else { lpObj->TargetNumber = -1; lpTargetObj = NULL; } } BOOL bRateSuccess = FALSE; int iCurrentState = lpObj->m_iCurrentAIState; int iMaxStateTransCount = this->m_AIStateTransCount[iCurrentState]; for ( int iPriority=0;iPriority<iMaxStateTransCount;iPriority++) { TMonsterAIState * AIState = &this->m_AIState[iCurrentState][iPriority]; BOOL bTransition = MAI_STATE_TRANS_VALUE_; // If there is an apropiate Value it is set to TRUE // Choose the right action according Transation Type switch ( AIState->m_iTransitionType ) { case MAI_STATE_TRANS_NO_ENEMY: if ( lpTargetObj == NULL ) { bTransition = TRUE; } break; case MAI_STATE_TRANS_IN_ENEMY: if ( lpTargetObj ) { if ( gObjCalDistance(lpObj, lpTargetObj) <= lpObj->m_AttackRange ) { bTransition = TRUE; } } break; case MAI_STATE_TRANS_OUT_ENEMY: if ( lpTargetObj ) { if ( gObjCalDistance(lpObj, lpTargetObj) > lpObj->m_AttackRange ) { bTransition = TRUE; } } break; //case MAI_STATE_TRANS_DIE_ENEMY: case MAI_STATE_TRANS_DEC_HP: if ( AIState->m_iTransitionValue > lpObj->Life ) { bTransition = TRUE; } break; case MAI_STATE_TRANS_IMMEDIATELY: bTransition = TRUE; break; case MAI_STATE_TRANS_DEC_HP_PER: { AIState->m_iTransitionValue = (AIState->m_iTransitionValue > 0)? AIState->m_iTransitionValue : 0; AIState->m_iTransitionValue = (AIState->m_iTransitionValue < 100 )? AIState->m_iTransitionValue : 100 ; int iLife = ((float)lpObj->AddLife + lpObj->MaxLife) * (float)AIState->m_iTransitionValue / 100.0f; if ( iLife > lpObj->Life ) { bTransition = TRUE; } } break; case MAI_STATE_TRANS_AGRO_UP: if ( lpTargetObj ) { if ( iMaxAgro >= AIState->m_iTransitionValue ) { bTransition = TRUE; } } break; case MAI_STATE_TRANS_AGRO_DOWN: if ( lpTargetObj ) { if ( iMaxAgro <= AIState->m_iTransitionValue ) { bTransition = TRUE; } } break; case MAI_STATE_TRANS_GROUP_SOMMON: if ( lpObj->m_iGroupNumber ) { if ( TMonsterAIGroup::FindGroupMemberToSommon(lpObj->m_Index, lpObj->m_iGroupNumber, lpObj->m_iGroupMemberGuid) ) { bTransition = TRUE; } } case MAI_STATE_TRANS_GROUP_HEAL: if ( lpObj->m_iGroupNumber ) { if ( TMonsterAIGroup::FindGroupMemberToHeal(lpObj->m_Index, lpObj->m_iGroupNumber, lpObj->m_iGroupMemberGuid, 5) ) { bTransition = TRUE; } } break; } // If is Wrong State if ( bTransition == FALSE ) continue; if ( (rand()%100) < AIState->m_iTransitionRate ) { bRateSuccess = TRUE; lpObj->m_iLastAutomataDelay = AIState->m_iDelayTime; return &this->m_AIState[iCurrentState][iPriority]; } } return NULL; }