void CCharacter::Update( float dTime ) { NNObject::Update(dTime); clock_t currentTime = clock(); ShowHitEffect(dTime); UpdateHPBar(); UpdateZindex(); UpdateAttackTarget(); //현재 얼어있는 상태라면 이동/공격이 불가 if(m_Freeze) { CheckMeltingTime(currentTime); } else { //AttackTarget을 설정하고 Attack이 가능하면(사정거리 체크) //공격하고 그렇지 않으면 이동, 시야에 없으면 앞으로 전진 if(TargetInRange()) { if( CheckAttackTiming(currentTime) ) { AttackEnemy(currentTime); } } else if (TargetInSight() ) { GoToAttackTarget(dTime); } else { GoForward(dTime); } } }
// called from CAttackHandler::Update() void CAttackGroup::Update(int frameNr) { int frameSpread = 30; unsigned int numUnits = units.size(); if (!numUnits) { // empty attack group, nothing to update return; } float3 groupPosition = GetGroupPos(); if (groupPosition == ERRORVECTOR) return; // this part of the code checks for nearby enemies and does focus fire/maneuvering if ((frameNr % frameSpread) == ((groupID * 4) % frameSpread)) { isShooting = false; // get all enemies within attack range float range = highestAttackRange + 100.0f; int numEnemies = ai->cheat->GetEnemyUnits(&ai->unitIDs[0], groupPosition, range); if (numEnemies > 0) { // select one of the enemies int enemySelected = SelectEnemy(numEnemies, groupPosition); // for every unit, pathfind to enemy perifery (with personal range - 10) then // if distance to that last point in the path is < 10 or cost is 0, attack if (enemySelected != -1) { AttackEnemy(enemySelected, numUnits, range, frameSpread); } } } if (pathToTarget.size() >= 2) { // AssignToTarget() was called for this group so // we have an attack position and path, just move // (movement may be slow due to spreading of orders) if (!isShooting && isMoving && (frameNr % 60 == (groupID * 5) % frameSpread)) { MoveAlongPath(groupPosition, numUnits); } } else { // find something to attack within visual and radar LOS if AssignToTarget() wasn't called if ((defending && !isShooting && !isMoving) && (frameNr % 60 == groupID % 60)) { FindDefenseTarget(groupPosition, frameNr); } } }
EBTNodeResult::Type UShootAtEnemyTask::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) { AMinionAIController* MinionController = Cast<AMinionAIController>(OwnerComp.GetAIOwner()); if (MinionController == NULL) { return EBTNodeResult::Failed; } AMinionCharacter* Minion = Cast<AMinionCharacter>(MinionController->GetPawn()); ABorderItem* Enemy = MinionController->GetEnemy(); if (CanAttack(Minion, Enemy)) { AttackEnemy(Minion, Enemy); return EBTNodeResult::InProgress; } else if (!Enemy) { return EBTNodeResult::Succeeded; } return EBTNodeResult::Failed; }