⬆️ ⬇️

Creating a simple bot for WoW: continued

This is a continuation of the previous article:

Creating a simple bot for the online game world of warcraft



In this part I will discuss the process of interaction with the auctioneer and the mailbox. If the previous part was more general, then this part is already more connected with the world of WoW and much will hardly be applicable to other online games.





')

In that article, we created a bot that can independently come to the NPC auctioneer. Now we need to implement our further actions. First, I will tell you a little about how the auction takes place. I personally trade symbols, but the addons that I use also automate the trading of any craft items. I use TradeSkill Master , this is an addon from the authors auction profit master, which used to be called quick auctions. The point is: I have about 400-500 of my items at auction. In addition to me on the server there are another 4-5 people who sell the same product in the same volumes. My task is to keep the price of the product all the time lower than theirs. This allows you to make an addon: it automatically scans the auction, if it finds that someone put the item at a price lower than mine, it removes my lot from the auction. The item is sent to the post office. Accordingly, it then needs to be picked up from the post office and put out at a price lower than that of competitors. The price is also assigned by the addon.



Those. in fact, the bot's task is to come to the auctioneer, open the auction window, start auctioning items, then start canceling lots when everything is canceled - go to the post office and pick up everything, then go back to the auction. Bot, who knows how to come to the NPC-auctioneer, we have already written. Now our task is to start trading.



Trade



There is already a clean AutoIt, with a little macro added.

We will need one macro that will target the auctioneer - this is

/   


We assign this macro, for example, to the button "9". Next we need to start trading with him. Here, too, everything is simple: in the settings of the assignment of keys, the section “functions of using targets”, you must assign the button “interact with a target”, I assigned it to “\” for example.

After the opening of the auction, you must start the process of placing goods from the bags to the auction. In my addon, this is desired by a simple click on the button, in other addons, it may take two clicks - it doesn't matter, all the same, the function is trivial:

 Func StartPostingAuc() Send("9") ;     Sleep(300) Send("\") ;   Sleep(2000);           -   MouseClick("left", 1278, 155) ;    " " Sleep(2000) $state = "posting" ;  EndFunc 




Actually the function of the posting is also quite simple. After clicking on the button we have this window:



There is a progress bar at the bottom, and a button appears at the top, on clicking on it our goods are put up for auction.

Accordingly, our task is to click on the button while there is a progress bar, as soon as the progress bar ends - proceed to the next step - the cancellation of goods for which the price was interrupted

 Func PostingAuc() $borderPixelColor = PixelGetColor(937,527);       -   ,   - While $borderPixelColor = 6249826 and $state = "posting" ;   - -  MouseClick("left", 1026, 210) Sleep(500); $borderPixelColor = PixelGetColor(937,527); Wend if $state = "posting" then ;    -     -  $state = "startcancel" EndIf EndFunc 




Cancellation is not fundamentally different from the posting, the same exact window with a progress bar and one button. Accordingly, the functions are exactly the same, just click. That's the whole process of trading.



Move to mailbox



After all canceled goods got to the post office, you need to pick them up from there. For this we go to the mailbox. In principle, the process of walking to the mailbox is almost the same as the process of walking to the auctioneer:

We also write a semaphore that will show where to go. We also rotate the coordinate system to make it easier to navigate. When a character is facing the mailbox, the angle is 2.31 rad.



The only difference is that when you walk in the direction of the mailbox there are protruding elements in the walls, into which I sometimes crashed, so when creating a semaphore, I took this moment into account and made it so that when I approach the wall I move away from it to the right. In principle, this was done by simply adding another branch to the if:

  elseif(mailPosX < 0.2000 and mailPosY > 0.896) then PlayerMailGoForvard:SetTexture(1,0,0); PlayerMailGoBack:SetTexture(1,0,0); PlayerMailGoLeft:SetTexture(1,0,0); PlayerMailGoRight:SetTexture(0,1,0); PlayerOnMail:SetTexture(1,0,0); 


Those. x <0.2 is until I leave the building, y> 0.896 - I approach the wall, I have to move. As soon as the wall left the building, there is no need to move away.



Now that the character has come to the mailbox, you must open it in some way.

The way as with the auctioneer does not work here - the mailbox can not be taken on target.

Therefore, a little preparation is required here: before launching the bot, it is necessary to bring the camera as close as possible and make it look ahead and down. Previously, api Vova allowed you to find out the current position of the camera, and you could write a semaphore to control the camera, but after enterprising people wrote an augmented reality addon that greatly simplified the player’s life, this function was forbidden to use in addons. Therefore, it is necessary to set up the camera manually when the bot starts: to interact with the auctioneer, it’s all the same how the camera is directed.



So, we came to the mailbox, the camera is pointing down. We see something like this:



Our task is to click on the mailbox with the right mouse button.

There are problems:

1. we can not guarantee exactly the point at which we will come, only about

2. mailbox can be blocked by another player



These problems mean the following: we cannot save the point we need to click on to open the mailbox, as we do in the case of other buttons.

But taking into account our algorithm for going to the mailbox, we believe that it will most likely be somewhere in the left third of the screen.

Correspondingly, we will write a function that will click first to the place where the mailbox is most often located, and if it does not find it, click on the left third of the screen until it finds it.

For 9 hours of testing, this function only 2 times could not find the mailbox, and it was my fault: the way to the box was poorly prescribed, the character fell from the ledge on which he stood and there was no box on the screen at all. The problem was solved by prescribing a condition in the semaphore, in which the character must step back a bit so as not to fall.

  elseif (mailposX > 0.203) then PlayerMailGoForvard:SetTexture(1,0,0); PlayerMailGoBack:SetTexture(0,1,0); PlayerMailGoLeft:SetTexture(1,0,0); PlayerMailGoRight:SetTexture(1,0,0); PlayerOnMail:SetTexture(1,0,0); 


Mailbox in the open state (at the top left you can see a piece of the updated semaphore, more compact):





Actually, we will determine the opening of the mailbox by the appearance of the red button “receive all”. The function for autoit I got is this:

 Func OpenMail() $x1 = 392 ; ,        $y1 = 382 While not (PixelGetColor(237,515) = 6226176) ;      -     MouseClick("right", $x1, $y1); $y1 = $y1 + 20 if $y1 > 620 Then $x1 = $x1 + 10 $y1 = 54 if $x1 > 650 and $y1 > 620 Then $x1 = 194 $y1 = 54 EndIf EndIf Sleep(200) Wend MouseClick("left", 237,515)4    -    Sleep(1000) MouseClick("left", 237,535);     $state = "givingmails";     EndFunc 


After clicking on the red button, it becomes gray until all letters are received.



Receive letters



In general, the receipt of letters works quite simply: you just need to stand and wait until the smart TradeSkillMaster extracts all the letters from the mail. As soon as the addon extracts everything - the button changes to red and you can go back to the auctioneer: we already know how.



It would seem that the bot was written. But then the biggest problems were waiting for me: to find out that all the letters had been received turned out to be not such a trivial task as it looked at first. In general, there are two ways to know that all letters have been received:

1. The button turned red again. The easiest option, unfortunately - the rarest.

2. The bags are filled - at the same time the button does not turn red and the bot could always stand and wait near the mail. To solve this problem, the bot automatically opens the last bag at startup and ensures that the last cell in it is empty. As soon as the color of the last cell of the bag changes, it means the bags are full, it's time to go to the auction

3. Sometimes trade skill master is buggy and some empty letters are not deleted from the mail. In this case, the button also never turns red, even if there are no more letters in the mail. In this case, the problem is solved simply: I took the last slot of the mail, and I see whether it changes or not: when I receive letters, they constantly move up and the slot changes. When all letters are received, it ceases to change. If it does not change within 20 seconds - then it’s time to go to exhibit the goods.



Total function turned out like this:

 Func GiveMails() if PixelGetColor(237,515) = 6226176 or $i = 25 or not (PixelGetColor(1665, 868) = 2761500) then ;        $state = "goingtoauc" $i = 0 EndIf if PixelGetColor(52,470) = $prevcolor then ;       ,      $i = $i+1 else $i = 0 EndIf $prevcolor = PixelGetColor(52,470) Sleep(1000) EndFunc 




Everything, we successfully received letters, we return to the auctioneer!




In general, I completed my development on this, because now my bot knows how to do everything that I originally wanted from him: comes to the auctioneer, exposes his items, cancels items with interrupted prices, comes to the post office, picks up his belongings, returns to the auction , exposes, and further in a circle.



As a conclusion, I want to say that the development of bots for online games is like a logical game:

How to make him pick up all the letters? How to bypass this or that feature? How best to implement this or that function? Weekends are considered well spent, a good warm-up for the brain :)

Source: https://habr.com/ru/post/113271/



All Articles