Openkore.com

OpenKore Forums
It is currently 11 Dec 2017, 09:16

All times are UTC - 5 hours [ DST ]





Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: [PATCH] Fixes: item pickup problems; deadlock attack positio
PostPosted: 01 Nov 2013, 18:18 
Offline
Noob
Noob

Joined: 01 Nov 2013, 17:47
Posts: 7
First, is needed for "pickup problems" and "deadlock positioning":

Code:
--- untouched/openkore_ready/src/Utils.pm   Sun Sep 08 22:00:04 2013
+++ openkore_ready/src/Utils.pm   Fri Nov 01 22:30:21 2013
@@ -38,7 +38,7 @@
   @{$Utils::DataStructures::EXPORT_TAGS{all}},

   # Math
-   qw(calcPosFromTime calcPosition calcTime checkMovementDirection countSteps distance
+   qw(calcPosFromTime calcPosition calcTime checkMovementDirection countSteps distance distance_steps
   intToSignedInt intToSignedShort
   blockDistance getVector moveAlong moveAlongVector
   normalize vectorToDegree max min round ceil),
@@ -291,6 +291,31 @@
         %line = %{$pos1};
     }
     return sqrt($line{x} ** 2 + $line{y} ** 2);
+}
+
+##
+# distance_steaps(r_hash1, r_hash2)
+# pos1, pos2: references to position hash tables.
+# Returns: the distance as a number.
+#
+# Calculates the maximum horizontal or vertical distance
+# between pos1 and pos2. Use this to find out if a position
+# is within your reach.
+#
+# FIXME: This is not actually the number of steps one
+# has to take to reach the target.
+#
+sub distance_steps {
+    my $pos1 = shift;
+    my $pos2 = shift;
+    return 0 if (!$pos1 || !$pos2);
+   
+    my ($dx, $dy) = (
+       abs($pos1->{x} - $pos2->{x}),
+       abs($pos1->{y} - $pos2->{y})
+    );
+   
+    return $dx > $dy ? $dx : $dy;
}

##

---

This fixes the annoying problem that openkore fails to pickup items so often:

Code:
--- untouched/openkore_ready/src/AI/CoreLogic.pm   Sat Jun 08 02:00:02 2013
+++ openkore_ready/src/AI/CoreLogic.pm   Fri Nov 01 22:35:33 2013
@@ -736,14 +738,32 @@
   if (AI::action eq "take" && !(my $item = $items{AI::args->{ID}})) {
      AI::dequeue;

+   } elsif (AI::action eq "take" && ($item->{take_failed} < 2) && timeOut(AI::args->{ai_take_giveup})) {
+      $item->{take_failed}++;
+      my $myPos = $char->{pos};
+      my $dist = distance_steps($item->{pos}, $myPos);
+      if ($dist > 0) {
+         AI::args->{ai_take_giveup}{time} = time(); # reset timer
+         if (!$config{itemsTakeAuto_new}) {
+            $char->move($item->{pos}{x}, $item->{pos}{y});
+         } else {
+            my $pos = $item->{pos};
+            message TF("Routing to (%s, %s) to take %s (%s), distance %s\n", $pos->{x}, $pos->{y}, $item->{name}, $item->{binID}, $dist);
+            ai_route($field->baseName, $pos->{x}, $pos->{y}, maxRouteDistance => $config{'attackMaxRouteDistance'});
+         }
+         message TF("Failed to take %s (%s) from (%s, %s) to (%s, %s) --- moving towards item\n", $item->{name}, $item->{binID}, $char->{pos}{x}, $char->{pos}{y}, $item->{pos}{x}, $item->{pos}{y});
+      } else {
+         message TF("Failed to take %s (%s) from (%s, %s) to (%s, %s) --- standing on top of it\n", $item->{name}, $item->{binID}, $char->{pos}{x}, $char->{pos}{y}, $item->{pos}{x}, $item->{pos}{y});
+         AI::dequeue;
+      }
   } elsif (AI::action eq "take" && timeOut(AI::args->{ai_take_giveup})) {
      message TF("Failed to take %s (%s) from (%s, %s) to (%s, %s)\n", $item->{name}, $item->{binID}, $char->{pos}{x}, $char->{pos}{y}, $item->{pos}{x}, $item->{pos}{y});
      $item->{take_failed}++;

I reuse the ai_take_giveup here, so one might actually want to lower it a bit. Otherwise the bot will wait twice as long for items it cannot pickup for legitimate reasons.

---

This fixes a deadlock(!) situation openkore encounters when it tries to attack mobs that wont move and the attack position it want's to move to is not walkable.

Example: (Mushroom)(empty)(tree)(bot)

Code:
--- untouched/openkore_ready/src/AI/Attack.pm   Sat Apr 06 03:00:02 2013
+++ openkore_ready/src/AI/Attack.pm   Tue Oct 29 23:40:22 2013
@@ -518,6 +521,29 @@
      $args->{monsterPos} = {%{$monsterPos}};

      my $pos = meetingPosition($target, $args->{attackMethod}{maxDistance});
+
+      if (not $field->isWalkable($pos->{x}, $pos->{y}) and distance_steps($realMyPos, $pos) < 2) {
+         # bad case of hitting a wall
+         # try to find an alternative position with the same distance
+         my ($tx, $ty, $td, $t) = (0,0,999, distance($realMonsterPos->{pos}, $pos));
+         for my $try ([-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, -1], [1, 0], [1, 1]) {
+            next unless $field->isWalkable($pos->{x} + $try->[0], $pos->{y} + $try->[1]);
+            next if distance_steps($realMyPos, { x => $pos->{x} + $try->[0], y => $pos->{y} + $try->[1]}) < 1;
+            my $d = abs($t - distance({ x => $pos->{x} + $try->[0], y => $pos->{y} + $try->[1]}, $pos));
+            if ($d < $td) {
+               ($tx, $ty, $td) = ($pos->{x} + $try->[0], $pos->{y} + $try->[1], $d);
+            }
+         }
+         if ($td < 999) {
+            ($pos->{x}, $pos->{y}) = ($tx, $ty);
+         } else {
+            # now what?
+            # move one random step
+            while (not $field->isWalkable($pos->{x}, $pos->{y})) {
+               ($pos->{x}, $pos->{y}) = ($realMyPos->{x} + int(rand(3)-2), $realMyPos->{y} + int(rand(3)-2));
+            }
+         }
+      }

      my $dist = sprintf("%.1f", $monsterDist);
      debug "Target distance $dist is >$args->{attackMethod}{maxDistance}; moving to target: " .

It is not perfect, some times the bot will do a little "sidestep & back" dance for a while, but it will break the deadlock eventually.

I tried to be very careful, but I only tested it with melee characters. But I think the LOS checking may prevent this from happening for the others.

---

And now a new feature. Or maybe a bug fix? I don't know, but autoStorage already works for items in the cart; this will do the same for autoSell:

Code:
--- untouched/openkore_ready/src/AI/CoreLogic.pm   Sat Jun 08 02:00:02 2013
+++ openkore_ready/src/AI/CoreLogic.pm   Fri Nov 01 22:35:33 2013
@@ -1483,6 +1503,37 @@
               noSitAuto => 1);
         }
      } else {
+
+      if (!defined($args->{'emptiedCart'})) {
+         # get item to sell from cart
+         $args->{'emptiedCart'} = 1;
+         if ($char->cartActive) {
+            my @getItems;
+            my $cartInventory = $cart{inventory};
+            my $max;
+   
+            $max = @{$cartInventory};
+            for (my $i = 0; $i < $max; $i++) {
+               my $cartItem = $cartInventory->[$i];
+               next unless ($cartItem);
+               my $control = items_control($cartItem->{name});
+               next unless ($control->{sell});
+               my $amount = $cartItem->{amount};
+               if ($amount > 0) {
+                  my %obj;
+                  $obj{index} = $i;
+                  $obj{amount} = $amount;
+                  push @getItems, \%obj;
+                  debug "Scheduling $cartItem->{name} ($i) x $obj{amount} for getting from cart to sell\n", "ai_autoCart";
+               }
+            }
+            if (@getItems) {
+               cartGet(\@getItems);
+               return;
+            }
+         }
+      }
+
         $args->{'npc'} = {};
         getNPCInfo($config{'sellAuto_npc'}, $args->{'npc'});
         if (!defined($args->{'sentSell'})) {

This will (partially) fail if the character becomes overweight with the stuff from the cart. With fail = not sell all items that are in the cart. Especially stacks that have to be split to be moved into the inventory won't work with this. But to do it right I'd have to change the autoSell logic big time.


Top
 Profile  
 
 Post subject: Re: [PATCH] Fixes: item pickup problems; deadlock attack positio
PostPosted: 03 Nov 2013, 19:32 
Offline
Administrator
Administrator
User avatar

Joined: 24 Apr 2008, 12:02
Posts: 1299
Nice one!
Developers/Testers please check this patch (may-be make modifications where needed) and to SVN asap. ;)

_________________
Join our Team. Click here.
Image


Image


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group