# Openkore.com

OpenKore Forums
 It is currently 11 Dec 2018, 19:52

 All times are UTC - 5 hours [ DST ]

 Page 1 of 1 [ 2 posts ]
 Print view Previous topic | Next topic
Author Message
 Post subject: [PATCH] Fixes: item pickup problems; deadlock attack positioPosted: 01 Nov 2013, 18:18
 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
+#
+# 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

 Post subject: Re: [PATCH] Fixes: item pickup problems; deadlock attack positioPosted: 03 Nov 2013, 19:32

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

_________________

Top

 Display posts from previous: All posts1 day7 days2 weeks1 month3 months6 months1 year Sort by AuthorPost timeSubject AscendingDescending
 Page 1 of 1 [ 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 forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum

Search for:
 Jump to:  Select a forum ------------------ Announcements    Announcements Support    Frequently Asked Questions & Guides    Resolved Questions    Official Servers       bRO       fRO       iRO       idRO       kRO       jRO       tRO       twRO       pRO       Private Servers       Other OpenKore support Discussions    Discussion    Tips & Tricks    Feature suggestions Plugins    Howto write plugins    Macro Plugin       Share your macro's    Other Plugins Technical    Developers Corner    Development Help    Tester's corner    Bug reports       Fixed bugs       Unresolvable bugs    Commit Queue Off Topic    Misc    Trashcan Links    OpenKore Manual    Official GitHub    Download Openkore .zip    AJAX IRC Client (Chat)    Developer Manual