From abcfcc85aac685227136f8be1e16a7b1217f1633 Mon Sep 17 00:00:00 2001 From: Henrique Date: Tue, 14 Jan 2025 17:19:15 -0300 Subject: [PATCH] fix route --- src/Task/Route.pm | 104 +++++++++++++++++++++++++++------------------- 1 file changed, 61 insertions(+), 43 deletions(-) diff --git a/src/Task/Route.pm b/src/Task/Route.pm index c08423d075..aae471dff9 100644 --- a/src/Task/Route.pm +++ b/src/Task/Route.pm @@ -211,7 +211,9 @@ sub iterate { my $pos = $self->{actor}{pos}; my $pos_to = $self->{actor}{pos_to}; - debug "Route $self->{actor}: Calculating. Your pos ($pos->{x} $pos->{y}). Your pos_to ($pos_to->{x} $pos_to->{y}).\n", "route"; + my $calc_pos = calcPosFromPathfinding($field, $self->{actor}); + + debug "Route $self->{actor}: Calculating. Your pos ($pos->{x} $pos->{y}). Your pos_to ($pos_to->{x} $pos_to->{y}). calcPosFromPathfinding ($calc_pos->{x} $calc_pos->{y})\n", "route"; my $begin = time; @@ -219,29 +221,28 @@ sub iterate { debug "Route $self->{actor}: Current position and destination are the same.\n", "route"; $self->setDone(); - } elsif ($self->getRoute($self->{solution}, $self->{dest}{map}, $pos, $self->{dest}{pos}, $self->{avoidWalls}, $self->{randomFactor}, $self->{useManhattan}, 1)) { + } elsif ($self->getRoute($self->{solution}, $self->{dest}{map}, $calc_pos, $self->{dest}{pos}, $self->{avoidWalls}, $self->{randomFactor}, $self->{useManhattan}, 1)) { $self->{stage} = ROUTE_SOLUTION_READY; - @{$self->{last_pos}}{qw(x y)} = @{$pos}{qw(x y)}; + @{$self->{last_pos}}{qw(x y)} = @{$calc_pos}{qw(x y)}; @{$self->{last_pos_to}}{qw(x y)} = @{$pos_to}{qw(x y)}; $self->{start} = 1; $self->{confirmed_correct_vector} = 0; - debug "Route $self->{actor} Solution Ready! Found path on ".$self->{dest}{map}->baseName." from ".$pos->{x}." ".$pos->{y}." to ".$self->{dest}{pos}{x}." ".$self->{dest}{pos}{y}.". Size: ".@{$self->{solution}}." steps.\n", "route"; - - # Changed in pathfinding.xs - #unshift(@{$self->{solution}}, { x => $pos->{x}, y => $pos->{y}}); + debug "Route $self->{actor} Solution Ready! Found path on ".$self->{dest}{map}->baseName." from ".$calc_pos->{x}." ".$calc_pos->{y}." to ".$self->{dest}{pos}{x}." ".$self->{dest}{pos}{y}.". Size: ".@{$self->{solution}}." steps.\n", "route"; $self->iterate(); } else { - debug "Something's wrong; there is no path from " . $self->{dest}{map}->baseName . "($pos->{x},$pos->{y}) to " . $self->{dest}{map}->baseName . "($self->{dest}{pos}{x},$self->{dest}{pos}{y}).\n", "debug"; + debug "Something's wrong; there is no path from " . $self->{dest}{map}->baseName . "($calc_pos->{x},$calc_pos->{y}) to " . $self->{dest}{map}->baseName . "($self->{dest}{pos}{x},$self->{dest}{pos}{y}).\n", "debug"; $self->setError(CANNOT_CALCULATE_ROUTE, "Unable to calculate a route."); } } elsif ($self->{stage} == ROUTE_SOLUTION_READY) { my $begin = time; my $solution = $self->{solution}; + + # TODO: What is this Fractional route motion bellow? if ($self->{maxDistance} > 0 && $self->{maxDistance} < 1) { # Fractional route motion $self->{maxDistance} = int($self->{maxDistance} * scalar(@{$solution})); @@ -253,11 +254,14 @@ sub iterate { my $final_pos = $self->{solution}[-1]; if ( ($self->{pyDistFromGoal} || $self->{distFromGoal}) && ($self->{dest}{pos}{x} != $final_pos->{x} || $self->{dest}{pos}{y} != $final_pos->{y}) ) { debug "Route $self->{actor} - final destination is not the same of pathfind, adjusting the trimsteps\n", "route"; + # TODO: Reviews this code bellow my $trim = blockDistance($self->{dest}{pos}, $final_pos); $self->{pyDistFromGoal} -= $trim if $self->{pyDistFromGoal}; $self->{distFromGoal} -= $trim if $self->{distFromGoal}; } - + + # TODO: Neither distFromGoal or pyDistFromGoal consider pathfinding, only blockdistance or distance + # - maybe this should be done during walk route in a loop? # Trim down solution tree for pyDistFromGoal or distFromGoal if ($self->{pyDistFromGoal}) { my $trimsteps = 0; @@ -304,7 +308,7 @@ sub iterate { $self->{step_index} = $config{$self->{actor}{configPrefix}.'route_step'}; } - my ($current_pos, $current_pos_to); + my ($current_pos, $current_pos_to, $current_calc_pos); # $actor->{pos} is the position the character moved FROM in the last move packet received @{$current_pos}{qw(x y)} = @{$self->{actor}{pos}}{qw(x y)}; @@ -312,7 +316,7 @@ sub iterate { # $actor->{pos_to} is the position the character moved TO in the last move packet received @{$current_pos_to}{qw(x y)} = @{$self->{actor}{pos_to}}{qw(x y)}; - my $current_calc_pos = calcPosFromPathfinding($field, $self->{actor}); + $current_calc_pos = calcPosFromPathfinding($field, $self->{actor}); if ($current_calc_pos->{x} == $solution->[$#{$solution}]{x} && $current_calc_pos->{y} == $solution->[$#{$solution}]{y}) { # Actor position is the destination; we've arrived at the destination @@ -329,54 +333,63 @@ sub iterate { } else { # Failsafe my $lookahead_failsafe_max = $self->{step_index} + 1; - my $lookahead_failsafe_count = 0; + my $lookahead_failsafe_count; # This looks ahead in the solution array and finds the closest position in it to our current {pos}, then it looks $lookahead_failsafe_max further, just to be sure - my $best_pos_step = 0; - my $next_best_pos_step_try = 1; - - while (1) { - if (adjustedBlockDistance($current_pos, $solution->[$best_pos_step]) > adjustedBlockDistance($current_pos, $solution->[$next_best_pos_step_try])) { - $best_pos_step = $next_best_pos_step_try; + + $lookahead_failsafe_count = 0; + my $best_index; + my $best_dist; + + foreach my $step_i (0..$#{$solution}) { + my $step = $solution->[$step_i]; + if ($step->{x} == $current_calc_pos->{x} && $step->{y} == $current_calc_pos->{y}) { + $best_index = $step_i; + $best_dist = 0; + last; + } + my $dist = adjustedBlockDistance($current_calc_pos, $step); + if (!defined $best_dist || $best_dist > $dist) { + $best_index = $step_i; + $best_dist = $dist; $lookahead_failsafe_count = 0; } else { $lookahead_failsafe_count++; - if ($lookahead_failsafe_count == $lookahead_failsafe_max) { - $lookahead_failsafe_count = 0; - last; - } } - $next_best_pos_step_try++; - - if ($next_best_pos_step_try > $#{$solution}) { + if ($lookahead_failsafe_count == $lookahead_failsafe_max) { last; } } + my $best_pos_step = $best_index; # This does the same, but with {pos_to} - my $best_pos_to_step = 0; - my $next_best_pos_to_step_try = 1; - while (1) { - if (adjustedBlockDistance($current_pos_to, $solution->[$best_pos_to_step]) > adjustedBlockDistance($current_pos_to, $solution->[$next_best_pos_to_step_try])) { - $best_pos_to_step = $next_best_pos_to_step_try; + undef $best_index; + undef $best_dist; + foreach my $step_i (0..$#{$solution}) { + my $step = $solution->[$step_i]; + if ($step->{x} == $current_pos_to->{x} && $step->{y} == $current_pos_to->{y}) { + $best_index = $step_i; + $best_dist = 0; + last; + } + my $dist = adjustedBlockDistance($current_pos_to, $step); + if (!defined $best_dist || $best_dist > $dist) { + $best_index = $step_i; + $best_dist = $dist; $lookahead_failsafe_count = 0; } else { $lookahead_failsafe_count++; - if ($lookahead_failsafe_count == $lookahead_failsafe_max) { - $lookahead_failsafe_count = 0; - last; - } } - $next_best_pos_to_step_try++; - - if ($next_best_pos_to_step_try > $#{$solution}) { + if ($lookahead_failsafe_count == $lookahead_failsafe_max) { last; } } + my $best_pos_to_step = $best_index; # Here there may be the need to check if 'pos' has changed yet best_pos_step is still the same, creating a lag in the movement # Last change in pos and pos_to put us in a walk path oposite to the desired one + # TODO: This confirmed_correct_vector could probably be removed if ($best_pos_step > $best_pos_to_step) { if ($self->{confirmed_correct_vector}) { debug "Route $self->{actor} - movement interrupted: reset route (last change in pos and pos_to put us in a walk path oposite to the desired one)\n", "route"; @@ -390,13 +403,16 @@ sub iterate { } # Last move was to the cell we are already at, lag?, buggy code? - if ($self->{start} || $best_pos_step == 0) { + if ($self->{start}) { + debug "Route $self->{actor} - not trimming down solution (" . @{$solution} . ") because we have not moved yet.\n", "route"; + + } elsif ($best_pos_step == 0) { debug "Route $self->{actor} - not trimming down solution (" . @{$solution} . ") because best_pos_step is 0.\n", "route"; } else { # Should we trimm only the known walk ones ($best_pos_step) or the known + the guessed (calcStepsWalkedFromTimeAndRoute)? Default was both. - # Currently testing delete up to known ($best_pos_step)(exclusive) + # Currently testing delete up to known + the guessed debug "Route $self->{actor} - trimming down solution (" . @{$solution} . ") by ".($best_pos_step)." steps\n", "route"; splice(@{$solution}, 0, $best_pos_step); @@ -469,7 +485,7 @@ sub iterate { # We're stuck my $msg = TF("Stuck at %s (%d,%d), while walking from (%d,%d) to (%d,%d).", $self->{dest}{map}->baseName, @{$self->{actor}{pos_to}}{qw(x y)}, - $current_pos->{x}, $current_pos->{y}, $self->{dest}{pos}{x}, $self->{dest}{pos}{y} + $current_calc_pos->{x}, $current_calc_pos->{y}, $self->{dest}{pos}{x}, $self->{dest}{pos}{y} ); $msg .= T(" Teleporting to unstuck.") if ($config{$self->{actor}{configPrefix}.'teleportAuto_unstuck'}); $msg .= "\n"; @@ -506,9 +522,10 @@ sub iterate { # But first, check whether the distance of the next point isn't abnormally large. # If it is, then we've moved to an unexpected place. This could be caused by auto-attack, for example. + # TODO: This should be calcDistFromPath or something like that my %nextPos = (x => $self->{next_pos}{x}, y => $self->{next_pos}{y}); - if (blockDistance(\%nextPos, $current_pos) > 17) { - debug "Route $self->{actor} - movement interrupted: reset route (the distance of the next point is abnormally large ($current_pos->{x} $current_pos->{y} -> $nextPos{x} $nextPos{y}))\n", "route"; + if (blockDistance(\%nextPos, $current_calc_pos) > 17) { + debug "Route $self->{actor} - movement interrupted: reset route (the distance of the next point is abnormally large ($current_calc_pos->{x} $current_calc_pos->{y} -> $nextPos{x} $nextPos{y}))\n", "route"; $self->{solution} = []; $self->{stage} = CALCULATE_ROUTE; @@ -521,7 +538,7 @@ sub iterate { } } - if ($current_pos_to->{x} == $self->{next_pos}{x} && $current_pos_to->{y} == $self->{next_pos}{y}) { + if (!$self->{start} && $current_pos_to->{x} == $self->{next_pos}{x} && $current_pos_to->{y} == $self->{next_pos}{y}) { debug "[Route] Not sending next step ($self->{next_pos}{x}, $self->{next_pos}{y}) because our pos_to is the same as it.\n", "route"; if ($self->{lastStep} == 1 && !$self->{sendAttackWithMove} && $self->{meetingSubRoute}) { debug "[Route] Also ending task now ang giving back control to AI::Attack.\n", "route"; @@ -539,6 +556,7 @@ sub iterate { @{$self->{last_pos}}{qw(x y)} = @{$current_pos}{qw(x y)}; @{$self->{last_pos_to}}{qw(x y)} = @{$current_pos_to}{qw(x y)}; + @{$self->{last_current_calc_pos}}{qw(x y)} = @{$current_calc_pos}{qw(x y)}; debug "Route $self->{actor} - next step moving to ($self->{next_pos}{x}, $self->{next_pos}{y}), index $self->{step_index}, $stepsleft steps left\n", "route";