Страница 1 из 1

Алгоритм выбора цели, выбор ближайщего монстра для атаки

Добавлено: Вс июн 28, 2009 4:54 pm
NyaNya
Суть проблемы следующая, радиус обзора не регулируется ибо убрано из исходников
смотреть тут - viewtopic.php?f=8&t=7901
Радиус обзора на сервере очень большой, поэтому крайне необходимо чтобы бот выбирал для атаки монстра находящегося к нему ближе всего, уже довольно долго мучаю конфиг но добиться нормального поведения от бота так не смог :( . Буду признателен за любую информацию по этому поводу.

Код: Выделить всё

lockMap ein_fild04
attackAuto 1
attackAuto_party 1
attackAuto_onlyWhenSafe 1
attackAuto_followTarget 0
attackAuto_inLockOnly 1
attackAuto_notInTown 1
attackDistance 10
attackDistanceAuto 0
attackMinDistance 0
attackMaxDistance 10
attackMaxRouteDistance 5
attackMaxRouteTime 1
attackMinPlayerDistance 15
attackMinPortalDistance 4
attackUseWeapon 0
attackNoGiveup 0
attackCanSnipe 1
attackCheckLOS 1
attackLooters 0
attackChangeTarget 2
aggressiveAntiKS 0

Код: Выделить всё

route_escape_unknownMap 1
route_escape_reachedNoPortal 1
route_escape_randomWalk 1
route_escape_shout
route_randomWalk 0 << пробовал как при 1 так и при 0 толку не какова...
route_randomWalk_inTown 0
route_randomWalk_maxRouteTime 2
route_randomWalk_maxRouteDistance 15
route_maxWarpFee
route_maxNpcTries 5
route_teleport 0
route_teleport_minDistance 150
route_teleport_maxTries 8
route_teleport_notInMaps
route_step 15
route_avoidWalls 1

Код: Выделить всё

attackSkillSlot Fire Bolt {
	lvl 10
	MinDist 3
	MaxDist 10
	sp > 10%
	monsters Geographer, Yellow Plant
#Green Plant, Red Plant, Yellow Plant, Blue Plant, White Plant, Shining Plant
}
mon_control.txt

Код: Выделить всё

all 0 2 0
Geographer 2 2 0  <<тут также пробовал 1 2 0
Yellow Plant 2 0 0  << и тут 1 0 0  ну и естественно attackAuto при этом в 2 устанавливал...

Re: Алгоритм выбора цели, выбор ближайщего монстра для атаки

Добавлено: Вс июн 28, 2009 7:26 pm
wxBotowod
мне кажется нужно мучать attack.pm или corelogic.pm

Re: Алгоритм выбора цели, выбор ближайщего монстра для атаки

Добавлено: Вс июн 28, 2009 9:10 pm
kLabMouse
NyaNya
По моему.. для АттакАуто есть несколько режимов.
В том числе, и выбор ближайшего моба.

Re: Алгоритм выбора цели, выбор ближайщего монстра для атаки

Добавлено: Пн июн 29, 2009 1:25 am
NyaNya
kLabMouse писал(а):NyaNya
По моему.. для АттакАуто есть несколько режимов.
В том числе, и выбор ближайшего моба.
По моему чтото такое когда то мелькало, но сейчас похоже все сходиться с мануалом а именно 3 режима...
файл corelogic.pm
функция sub processAutoAttack {

Код: Выделить всё

if (!AI::is(qw/sitAuto take items_gather items_take/)
				 && $config{'attackAuto'} >= 2 && !$ai_v{sitAuto_forcedBySitCommand}
				 && $attackOnRoute >= 2 && !$monster->{dmgFromYou} && $safe
				 && !positionNearPlayer($pos, $playerDist) && !positionNearPortal($pos, $portalDist)
				 && timeOut($monster->{attack_failed}, $timeout{ai_attack_unfail}{timeout})) {
					push @cleanMonsters, $_;
				}
1 - атака только в ответ, 2 агрессивно атаковать мобов.

От тудаже

Код: Выделить всё

if (!$attackTarget) {
				# No party monsters either; look for the closest, non-aggressive monster that:
				# 1) nobody's attacking
				# 2) has the highest priority

				undef $smallestDist;
				foreach (@cleanMonsters) {
					my $monster = $monsters{$_};
					next unless $monster;
					my $pos = calcPosition($monster);
					my $dist = distance($myPos, $pos);
					my $name = lc $monster->{name};

					if (!defined($smallestDist) || $priority{$name} > $highestPri
					  || ( $priority{$name} == $highestPri && $dist < $smallestDist )) {
						$smallestDist = $dist;
						$attackTarget = $_;
						$highestPri = $priority{$monster};
					}
				}
			}
На первый взгляд все правильно но почему тогда кор пытается идти через пол карты к дальнему гео?
При том что рандом валк отклчен.

Добавлено спустя 1 час 50 минут 33 секунды:
wxBotowod писал(а):мне кажется нужно мучать attack.pm или corelogic.pm
Помучал и вот что вышло
файл corelogic.pm
функция sub processAutoAttack

Код: Выделить всё

		### Step 1: Generate a list of all monsters that we are allowed to attack. ###
			my @aggressives;
			my @partyMonsters;
			my @cleanMonsters;

			# List aggressive monsters
			@aggressives = ai_getAggressives(1) if ($config{'attackAuto'} && $attackOnRoute);

			# There are two types of non-aggressive monsters. We generate two lists:
			foreach (@monstersID) {
				next if (!$_ || !checkMonsterCleanness($_));
				my $monster = $monsters{$_};
				# Ignore ignored monsters in mon_control.txt
				if (my $control = mon_control($monster->{name},$monster->{nameID})) {
					next if ( ($control->{attack_auto} ne "" && $control->{attack_auto} <= 0)
						|| ($control->{attack_lvl} ne "" && $control->{attack_lvl} > $char->{lv})
						|| ($control->{attack_jlvl} ne "" && $control->{attack_jlvl} > $char->{lv_job})
						|| ($control->{attack_hp}  ne "" && $control->{attack_hp} > $char->{hp})
						|| ($control->{attack_sp}  ne "" && $control->{attack_sp} > $char->{sp})
						|| ($control->{attack_auto} == 3 && ($monster->{dmgToYou} || $monster->{missedYou} || $monster->{dmgFromYou}))
						);
				}
				my $pos = calcPosition($monster);

############################################################################################
				# Ignore monsters with a distance greater than attack_MaxDistanceToBeginAttack.##########
############################################################################################
				if (distance(calcPosition($char), $pos) >= ($config{attack_MaxDistanceToBeginAttack} || 35)) {
				next;
				}
Добавленные строки

Код: Выделить всё

############################################################################################
				# Ignore monsters with a distance greater than attack_MaxDistanceToBeginAttack.##########
############################################################################################
				if (distance(calcPosition($char), $pos) >= ($config{attack_MaxDistanceToBeginAttack} || 35)) {
				next;
				}
Ну и в конфиге необходимо прописать

Код: Выделить всё

attack_MaxDistanceToBeginAttack 20
Кора не будет атаковать мобов находящихся на расстоянии больше чем указанно в attack_MaxDistanceToBeginAttack либо если значение не установлено 35.

Так бот работает гораздо лучше... и практически не ошибается.

Добавлено спустя 2 минуты:
Однако так и осталось загадкой почему не выберается ближайший моб

Re: Алгоритм выбора цели, выбор ближайщего монстра для атаки

Добавлено: Вт июн 30, 2009 1:43 am
BesT
Вот решения вашей проблемы!


Для етого вам нада в папке: "src" в файле: "Misc.pm" изменить:

Код: Выделить всё

if (!defined($highestPri) || ($priority{$name} > $highestPri)) {
                    $highestPri = $priority{$name};
                    $smallestDist = $dist;
                    $bestTarget = $_;
               }
               if ((!defined($highestPri) || $priority{$name} == $highestPri)
                 && (!defined($smallestDist) || $dist < $smallestDist)) {
                    $highestPri = $priority{$name};
                    $smallestDist = $dist;
                    $bestTarget = $_;
               }
Их несколько, и нада их все изменять.

Находиится в блоке: "sub getBestTarget"

поменять на ето:

Код: Выделить всё

if (!defined($smallestDist) || $dist < $smallestDist) {
                        $smallestDist = $dist;
                        $bestTarget = $_;
                   }

У меня перебоев нет, цель выберется ближнея...

Добавлено спустя 4 минуты 49 секунд:
Посте изменений блок выглядит так:

Код: Выделить всё

sub getBestTarget {
        my ($possibleTargets, $nonLOSNotAllowed) = @_;
        if (!$possibleTargets) {
                return;
        }

        my $portalDist = $config{'attackMinPortalDistance'} || 4;
        my $playerDist = $config{'attackMinPlayerDistance'} || 1;

        my @noLOSMonsters;
        my $myPos = calcPosition($char);
        my ($highestPri, $smallestDist, $bestTarget);

        # First of all we check monsters in LOS, then the rest of monsters

        foreach (@{$possibleTargets}) {
                my $monster = $monsters{$_};
                my $pos = calcPosition($monster);
                next if (positionNearPlayer($pos, $playerDist)
                        || positionNearPortal($pos, $portalDist)
                );
                if ((my $control = mon_control($monster->{name},$monster->{nameID}))) {
                        next if ( ($control->{attack_auto} == -1)
                                || ($control->{attack_lvl} ne "" && $control->{attack_lvl} > $char->{lv})
                                || ($control->{attack_jlvl} ne "" && $control->{attack_jlvl} > $char->{lv_job})
                                || ($control->{attack_hp}  ne "" && $control->{attack_hp} > $char->{hp})
                                || ($control->{attack_sp}  ne "" && $control->{attack_sp} > $char->{sp})
                                || ($control->{attack_auto} == 3 && ($monster->{dmgToYou} || $monster->{missedYou} || $monster->{dmgFromYou}))
                                || ($control->{attack_auto} == 0 && !($monster->{dmgToYou} || $monster->{missedYou}))
                        );
                }
                if ($config{'attackCanSnipe'}) {
                        if (!checkLineSnipable($myPos, $pos)) {
                                push(@noLOSMonsters, $_);
                                next;
                        }
                } else {
                        if (!checkLineWalkable($myPos, $pos)) {
                                push(@noLOSMonsters, $_);
                                next;
                        }
                }
                my $name = lc $monster->{name};
                my $dist = round(distance($myPos, $pos));
                
                # COMMENTED (FIX THIS): attackMaxDistance should never be used as indication of LOS
                #     The objective of attackMaxDistance is to determine the range of normal attack,
                #     and not the range of character's ability to engage monsters
                ## Monsters that aren't in attackMaxDistance are not checked up
                ##if ($nonLOSNotAllowed && ($config{'attackMaxDistance'} < $dist)) {
                ##      next;
                ##}
                if (!defined($smallestDist) || $dist < $smallestDist) {
                        $smallestDist = $dist;
                        $bestTarget = $_;
                }

        }
        if (!$nonLOSNotAllowed && !$bestTarget && scalar(@noLOSMonsters) > 0) {
                foreach (@noLOSMonsters) {
                        # The most optimal solution is to include the path lenghts' comparison, however it will take
                        # more time and CPU resources, so, we use rough solution with priority and distance comparison

                        my $monster = $monsters{$_};
                        my $pos = calcPosition($monster);
                        my $name = lc $monster->{name};
                        my $dist = round(distance($myPos, $pos));
                        if (!defined($highestPri) || ($priority{$name} > $highestPri)) {
                                $highestPri = $priority{$name};
                                $smallestDist = $dist;
                                $bestTarget = $_;
                        }
                        if ((!defined($highestPri) || $priority{$name} == $highestPri)
                          && (!defined($smallestDist) || $dist < $smallestDist)) {
                                $highestPri = $priority{$name};
                                $smallestDist = $dist;
                                $bestTarget = $_;
                        }
                }
        }
        return $bestTarget;
}

Re: Алгоритм выбора цели, выбор ближайщего монстра для атаки

Добавлено: Вт июн 30, 2009 11:18 am
NyaNya
Благодарю всех кто откликнулся на мой вопрос)
и спасибо за ответ BesT)) хотя он не решает мою проблему ,почему напишу ниже, но заставил меня еще покопаться в исходниках и похоже таки разобраться с этой мерзостью).

А не помогло потому что у нас видимо довольно сильно разные версии бота так как в моей все что касается выбора цели для атаки вынесено в файл srcAICoreLogic.pm
И так собственно решение
в файле srcAICoreLogic.pm необходимо нати следующий код в функции sub processAutoAttack

Код: Выделить всё

if (!$attackTarget) {
				# No party monsters either; look for the closest, non-aggressive monster that:
				# 1) nobody's attacking
				# 2) has the highest priority

				undef $smallestDist;
				foreach (@cleanMonsters) {
					my $monster = $monsters{$_};
					next unless $monster;
					my $pos = calcPosition($monster);
					my $dist = distance($myPos, $pos);
					my $name = lc $monster->{name};

					if (!defined($smallestDist) || $priority{$name} > $highestPri
					  || ( $priority{$name} == $highestPri && $dist < $smallestDist )) {
						$smallestDist = $dist;
						$attackTarget = $_;
						$highestPri = $priority{$monster};
					}
				}
			}
И заменить его на

Код: Выделить всё

if (!$attackTarget) {
				# No party monsters either; look for the closest, non-aggressive monster that:
				# 1) nobody's attacking
				# 2) has the highest priority

				undef $smallestDist;
				foreach (@cleanMonsters) {
					my $monster = $monsters{$_};
					next unless $monster;
					my $pos = calcPosition($monster);
					my $dist = distance($myPos, $pos);
					
					if ((!defined($smallestDist)) 
					  || ($priority{$monster} > $highestPri) 
                                          || (($priority{$monster} == $highestPri) && ($dist < $smallestDist))) {
						$smallestDist = $dist;
						$attackTarget = $_;
						$highestPri = $priority{$monster};
					}
				}
			}
Фактически удаляем строчку my $name = lc $monster->{name};
и вместо $priority{$name} вписываем $priority{$monster};
В перле я особо не разбираюсь но без данных изменений бот часто пропускает моба находящего буквально возле него и идет к дальнему...
Еще мне непонятно какой у моба будет приоритет если он не описан в priority.txt ?

Прикрепил к сообщению архив с отредактированным файлом.

П.С.
то BesT Земляк :wink:

Добавлено спустя 7 часов 28 минут 22 секунды:
Кстате... может боян, но логичнее было бы если бы бот выбирал для атаки не самого ближнего к нему моба, а моба до которого самый короткий маршрут, может кто нибудь подскажет есть ли функция для вычисления длинны маршрута?
Фактически такаяже проверка, только, вместо расчета дистанца будет рассчитываться дистанс маршрута...

Re: Алгоритм выбора цели, выбор ближайщего монстра для атаки

Добавлено: Вт июн 30, 2009 11:21 am
kLabMouse
NyaNya писал(а):Добавлено спустя 7 часов 28 минут 22 секунды:
Кстате... может боян, но логичнее было бы если бы бот выбирал для атаки не самого ближнего к нему моба, а моба до которого самый короткий маршрут, может кто нибудь подскажет есть ли функция для вычисления длинны маршрута?
Фактически такаяже проверка, только, вместо расчета дистанца будет рассчитываться дистанс маршрута...
Вариант тяжёлый.
По умолчанию, в коре нет оптимизации/кеширования результатов алгоритма А*.

Re: Алгоритм выбора цели, выбор ближайщего монстра для атаки

Добавлено: Вт июн 30, 2009 11:56 am
NyaNya
тяжелый но интересно на сколько, в принципе перед атакой просчитывать скажем 10 коротких роутов и 2 длинные, к тому же сделать расчет с отсечением, тоесть скажем функция расчет_растояния_маршрута(координат чара, координаты моба, тек минимальное растояние)
если чилсо блоков привышает тек минимальное растояние то скажем возвращаем егоже +1; или там код -1. Както так...

Добавлено спустя 26 минут 54 секунды:
По идее есть еще такая опция - attackMaxRouteDistance
Если эта опция указана, Кора не будет идти дальше чем указанное число клеток чтобы атаковать цель. Это используется для того чтоб избежать обхода длинных стен/склонов чтоб атаковать цель.
Но нашлась она в странных местах... к томуже создается чувство что кора ее игнорит...
в Network\Receive.pm
в функции sub skill_cast

Код: Выделить всё

			my (%vec, %pos);
			getVector(\%vec, \%coords, $char->{pos_to});
			moveAlongVector(\%pos, $char->{pos_to}, \%vec, distance($char->{pos_to}, \%coords));
			ai_route($field{name}, $pos{x}, $pos{y},
				maxRouteDistance => $config{attackMaxRouteDistance},
				maxRouteTime => $config{attackMaxRouteTime},
				noMapRoute => 1);
			message TF("Avoid casting Skill - switch position to : %s,%s\n", $pos{x}, $pos{y}), 1;
		}
И в коре лоджике в проверке на подъем лута...

Re: Алгоритм выбора цели, выбор ближайщего монстра для атаки

Добавлено: Вс сен 06, 2009 10:21 pm
kLabMouse
МММ.. диффни.

Re: Алгоритм выбора цели, выбор ближайщего монстра для атаки

Добавлено: Пн сен 07, 2009 10:12 am
kLabMouse
Бля. Лучше бы разницу между твоим и тем который в СВНке.