BOOL TMonsterAIElement::ApplyElementSkillAttack(int iIndex, int iTargetIndex, TMonsterAIState * pAIState) { LPOBJ lpObj = &gObj[iIndex]; if ( TMonsterSkillManager::CheckMonsterSkill(lpObj->Class) ) { BOOL bEnableAttack = TRUE; if ( lpObj->TargetNumber < 0 ) { lpObj->TargetNumber = -1; lpObj->m_ActState.Emotion = 0; lpObj->m_ActState.Attack = 0; lpObj->m_ActState.Move = 0; lpObj->NextActionTime = 1000; return FALSE; } if ( !gObj[lpObj->TargetNumber].Live || gObj[lpObj->TargetNumber].Teleport ) bEnableAttack = FALSE; if ( gObj[lpObj->TargetNumber].Connected <= PLAYER_LOGGED || gObj[lpObj->TargetNumber].CloseCount != -1 ) { bEnableAttack = FALSE; } if ( !bEnableAttack ) { lpObj->TargetNumber = -1; lpObj->m_ActState.Emotion = 0; lpObj->m_ActState.Attack = 0; lpObj->m_ActState.Move = 0; lpObj->NextActionTime = 1000; return FALSE; } LPOBJ lpTargetObj = &gObj[lpObj->TargetNumber]; lpObj->Dir = GetPathPacketDirPos(lpTargetObj->X - lpObj->X, lpTargetObj->Y - lpObj->Y); int iRate1 = this->m_iTargetType; int iRate2 = this->m_iX; int iRate3 = this->m_iY; int iRandom = rand() % 100; if ( iRandom < iRate1 ) TMonsterSkillManager::UseMonsterSkill(lpObj->m_Index, lpObj->TargetNumber, 0, -1, 0); else if ( iRandom < (iRate1+iRate2) ) TMonsterSkillManager::UseMonsterSkill(lpObj->m_Index, lpObj->TargetNumber, 1, -1, 0); else if ( iRandom < (iRate1+iRate2+iRate3) ) TMonsterSkillManager::UseMonsterSkill(lpObj->m_Index, lpObj->TargetNumber, 2, -1, 0); lpObj->m_ActState.Attack = 0; return FALSE; } return FALSE; }
BOOL TMonsterAIUtil::FindPathToMoveMonster(LPOBJ lpObj, int iTargetX, int iTargetY, int iMaxPathCount, BOOL bPreventOverMoving) { if ( TMonsterAIUtil::CheckMovingCondition(lpObj)==FALSE) return FALSE; PATH_t Path; BOOL bPathFound = FALSE; #ifndef DOPPEL if ( bPreventOverMoving ) bPathFound = MapC[lpObj->MapNumber].PathFinding2(lpObj->X, lpObj->Y, iTargetX, iTargetY, &Path); else bPathFound = MapC[lpObj->MapNumber].PathFinding4(lpObj->X, lpObj->Y, iTargetX, iTargetY, &Path); #else if ( bPreventOverMoving == 1 ) bPathFound = MapC[lpObj->MapNumber].PathFinding2(lpObj->X, lpObj->Y, iTargetX, iTargetY, &Path); else if ( bPreventOverMoving == 2 ) bPathFound = MapC[lpObj->MapNumber].PathFinding3(lpObj->X, lpObj->Y, iTargetX, iTargetY, &Path); else bPathFound = MapC[lpObj->MapNumber].PathFinding4(lpObj->X, lpObj->Y, iTargetX, iTargetY, &Path); #endif if (bPathFound ) { lpObj->m_LastMoveTime = GetTickCount(); int iTargetX; int iTargetY; int iStartX; int iStartY; int iResultX; int iResultY; BYTE btTargetDir = 0; iStartX = lpObj->X; iStartY = lpObj->Y; iResultX = lpObj->X; iResultY = lpObj->Y; lpObj->PathCount = Path.PathNum; lpObj->PathCur = 1; lpObj->PathStartEnd = 1; if ( lpObj->PathCount > iMaxPathCount ) lpObj->PathCount = iMaxPathCount; lpObj->PathX[0] = lpObj->X; lpObj->PathY[0] = lpObj->Y; lpObj->PathDir[0] = lpObj->Dir; for(int n=1;n<lpObj->PathCount;n++) { iTargetX = Path.PathX[n]; iTargetY = Path.PathY[n]; btTargetDir = GetPathPacketDirPos(iTargetX-iStartX, iTargetY-iStartY); lpObj->PathX[n] = iTargetX; lpObj->PathY[n] = iTargetY; lpObj->PathDir[n] = btTargetDir; iResultX += RoadPathTable[btTargetDir*2]; iResultY += RoadPathTable[btTargetDir*2+1]; } lpObj->MTX = iResultX; lpObj->MTY = iResultY; lpObj->TX = iResultX; lpObj->TY = iResultY; if ( lpObj->PathCount > 0 ) { MapC[lpObj->MapNumber].ClearStandAttr(iStartX, iStartY); MapC[lpObj->MapNumber].SetStandAttr(iResultX, iResultY); lpObj->m_OldX = iStartX; lpObj->m_OldY = iStartY; } } if ( bPathFound ) { this->SendMonsterMoveMsg(lpObj); return TRUE; } return FALSE; }
BOOL TMonsterAIUtil::GetXYToChase(LPOBJ lpObj) { int tpx; // Target Player X int tpy; int mtx; // Monster Target X int mty; int searchp = 0; int sn = 0; int searchcount = MAX_ROAD_PATH_TABLE/2-1; BYTE attr; BOOL result = 0; LPOBJ lpTargetObj; if ( OBJMAX_RANGE(lpObj->TargetNumber) == FALSE ) { return FALSE; } lpTargetObj = &gObj[lpObj->TargetNumber]; tpx = lpTargetObj->X; mtx = tpx; tpy = lpTargetObj->Y; mty = tpy; int dis = lpObj->m_AttackRange / sqrt(2.0); if ( lpObj->X < mtx ) { tpx -= dis; } if ( lpObj->X > mtx ) { tpx += dis; } if ( lpObj->Y < mty ) { tpy -= dis; } if ( lpObj->Y > mty ) { tpy += dis; } searchp = GetPathPacketDirPos( (lpTargetObj->X - tpx), (lpTargetObj->Y - tpy) ) * 2; if ( MapC[lpObj->MapNumber].GetStandAttr(tpx, tpy) == 0 ) { while ( searchcount-- ) { mtx = lpTargetObj->X + RoadPathTable[searchp]; mty = lpTargetObj->Y + RoadPathTable[1+searchp]; attr = MapC[lpObj->MapNumber].GetAttr(mtx, mty); if ( (attr&1) != 1 && (attr&2) != 2 && (attr&4) != 4 && (attr&8) != 8 ) { lpObj->MTX = mtx; lpObj->MTY = mty; return TRUE; } searchp += 2; if ( searchp > MAX_ROAD_PATH_TABLE-1 ) { searchp = 0; } } return FALSE; } attr = MapC[lpObj->MapNumber].GetAttr(tpx, tpy); if ( (attr&1) != 1 && (attr&2) != 2 && (attr&4) != 4 && (attr&8) != 8 ) { lpObj->MTX = tpx; lpObj->MTY = tpy; return TRUE; } return FALSE; }
BOOL TMonsterAIElement::ApplyElementAttack(int iIndex, int iTargetIndex, TMonsterAIState * pAIState) { LPOBJ lpObj = &gObj[iIndex]; UTIL.SendCrywolfChattingMsg(iIndex, "Element-공격"); if ( TMonsterSkillManager::CheckMonsterSkill(lpObj->Class) ) { BOOL bEnableAttack = TRUE; if ( lpObj->TargetNumber < 0 ) { lpObj->TargetNumber = -1; lpObj->m_ActState.Emotion = 0; lpObj->m_ActState.Attack = 0; lpObj->m_ActState.Move = 0; lpObj->NextActionTime = 1000; return FALSE; } if ( !gObj[lpObj->TargetNumber].Live || gObj[lpObj->TargetNumber].Teleport ) bEnableAttack = FALSE; if ( gObj[lpObj->TargetNumber].Connected <= PLAYER_LOGGED || gObj[lpObj->TargetNumber].CloseCount != -1 ) { bEnableAttack = FALSE; } if ( !bEnableAttack ) { lpObj->TargetNumber = -1; lpObj->m_ActState.Emotion = 0; lpObj->m_ActState.Attack = 0; lpObj->m_ActState.Move = 0; lpObj->NextActionTime = 1000; return FALSE; } LPOBJ lpTargetObj = &gObj[lpObj->TargetNumber]; lpObj->Dir = GetPathPacketDirPos(lpTargetObj->X - lpObj->X, lpTargetObj->Y - lpObj->Y); if ( (rand()%4) == 0 ) { PMSG_ATTACK pAttackMsg; pAttackMsg.AttackAction = 0x78; pAttackMsg.DirDis = lpObj->Dir; pAttackMsg.NumberH = SET_NUMBERH(lpObj->TargetNumber); pAttackMsg.NumberL = SET_NUMBERL(lpObj->TargetNumber); GCActionSend(lpObj, 0x78, lpObj->m_Index, 0); gObjAttack(lpObj, &gObj[lpObj->TargetNumber], 0, 0, 0, 0, 0,0,0); } else { TMonsterSkillManager::UseMonsterSkill(lpObj->m_Index, lpObj->TargetNumber, 0, -1, 0); } lpObj->m_ActState.Attack = 0; return FALSE; } else { if( lpObj->TargetNumber < 0 ) return FALSE; LPOBJ lpTargetObj = &gObj[lpObj->TargetNumber]; lpObj->Dir = GetPathPacketDirPos(lpTargetObj->X - lpObj->X, lpTargetObj->Y - lpObj->Y); PMSG_ATTACK pAttackMsg; pAttackMsg.AttackAction = 0x78; pAttackMsg.DirDis = lpObj->Dir; pAttackMsg.NumberH = SET_NUMBERH(lpObj->TargetNumber); pAttackMsg.NumberL = SET_NUMBERL(lpObj->TargetNumber); CGAttack((PMSG_ATTACK *)&pAttackMsg, lpObj->m_Index); GCActionSend(lpObj, 0x78, lpObj->m_Index, lpTargetObj->m_Index); gObjAttack(lpObj, &gObj[lpObj->TargetNumber], 0, 0, 0, 0, 0,0,0); return FALSE; } }
void MonsterHerd::MonsterBaseAct(LPOBJ lpObj) { LPOBJ lpTargetObj = NULL; if ( lpObj->TargetNumber >= 0 ) { lpTargetObj = &gObj[lpObj->TargetNumber]; } else { lpObj->m_ActState.Emotion = 0; } switch ( lpObj->m_ActState.Emotion ) { case 0: { if ( lpObj->m_ActState.Attack != 0 ) { lpObj->m_ActState.Attack = 0; lpObj->TargetNumber = -1; lpObj->NextActionTime = 500; } int actcode1 = rand() % 2; if ( actcode1 == 0 ) { lpObj->m_ActState.Rest = 1; lpObj->NextActionTime = 500; } else if ( lpObj->m_MoveRange > 0 ) { if ( lpObj->m_SkillHarden == 0 ) { this->MonsterMoveAction(lpObj); } } if ( lpObj->m_bIsMonsterAttackFirst != false ) { lpObj->TargetNumber = gObjMonsterSearchEnemy(lpObj, OBJ_USER); if ( lpObj->TargetNumber >= 0 ) { lpObj->m_ActState.EmotionCount = 30; lpObj->m_ActState.Emotion = 1; } } } break; case 1: if ( lpObj->m_ActState.EmotionCount > 0 ) { lpObj->m_ActState.EmotionCount --; } else { lpObj->m_ActState.Emotion = 0; } if ( lpObj->TargetNumber >= 0 && lpObj->PathStartEnd == 0 ) { int dis = gObjCalDistance(lpObj, lpTargetObj); int attackRange; if ( lpObj->m_AttackType >= 100 ) { attackRange = lpObj->m_AttackRange + 2; } else { attackRange = lpObj->m_AttackRange; } if ( dis <= attackRange ) { int tuser = lpObj->TargetNumber; int map = gObj[tuser].MapNumber; if ( MapC[map].CheckWall(lpObj->X, lpObj->Y, gObj[tuser].X, gObj[tuser].Y) == TRUE ) { BYTE attr = MapC[map].GetAttr(gObj[tuser].X, gObj[tuser].Y); if ( (attr&1) != 1 ) { lpObj->m_ActState.Attack = 1; lpObj->m_ActState.EmotionCount = (rand()%30+20); } else { lpObj->TargetNumber = -1; lpObj->m_ActState.EmotionCount = 30; lpObj->m_ActState.Emotion = 1; } lpObj->Dir = GetPathPacketDirPos(lpTargetObj->X-lpObj->X, lpTargetObj->Y-lpObj->Y); lpObj->NextActionTime = lpObj->m_AttackSpeed; } } else { if ( gObjMonsterGetTargetPos(lpObj) == TRUE ) { if ( MapC[lpObj->MapNumber].CheckWall(lpObj->X, lpObj->Y, lpObj->MTX, lpObj->MTY) == TRUE ) { lpObj->m_ActState.Move = 1; lpObj->NextActionTime = 400; lpObj->Dir = GetPathPacketDirPos(lpTargetObj->X - lpObj->X, lpTargetObj->Y-lpObj->Y); } else { this->MonsterMoveAction(lpObj); lpObj->m_ActState.Emotion = 3; lpObj->m_ActState.EmotionCount = 10; } } else { this->MonsterMoveAction(lpObj); lpObj->m_ActState.Emotion = 3; lpObj->m_ActState.EmotionCount = 10; } } } break; case 3: if ( lpObj->m_ActState.EmotionCount > 0 ) { lpObj->m_ActState.EmotionCount--; } else { lpObj->m_ActState.Emotion = 0; } lpObj->m_ActState.Move = 0; lpObj->m_ActState.Attack = 0; lpObj->NextActionTime = 400; break; } }