What's new
  • Visit Rebornbuddy
  • Visit Panda Profiles
  • Visit LLamamMagic
  • Visit Resources
  • Visit Downloads
  • Visit Portal

Writing a bot that run map, but got some questions

lau235623

New Member
Joined
Jun 3, 2014
Messages
27
Reaction score
0
I am going for a bot that will withdraw map in stash and run that in map device, here is my design flow:
  1. Check there is map in inventory
  2. If not, withdraw one in stash
  3. Go to Lab, open the Map Device and put map on it, active it then
  4. Use take closest portal to enter map.
  5. ???

I am not sure if the take closest portal api is the correct use in this place.
I also have no idea about is there any thing I need to do after player went into map?

Besides, I would like to allow user to change some setting in plugin (plugin is developed), can the bot read plugin's setting?
 
Last edited:
Moved to "Community Developer Forum".

Upon testing a few things when writing this post, I noticed an offset not currently used by the bot broke, so it will be updated soon to work again for the next version. Right now, you can't click the Activate button, because the logic needs to be updated for the current client version.

When writing a bot, it helps to break down the task into a bunch of smaller, easy to manage sub-tasks, and build up from there.

There's two parts to the task, the town stuff of getting the maps and traveling to the map room, and then the map room process of starting the map and then taking the portals.

I'll start you out with the 2nd half. Let's say you had a ready to use map in your inventory and you're already at the map room. What do you want to do?

Well, first you want to find the Map Device object first and interact with it. MapDevice will be in the next beta, but it's basically just ObjectManager.GetObjectByName("Map Device");
Code:
var mapDevice = LokiPoe.ObjectManager.MapDevice;
if (mapDevice == null)
{
// todo: handle error
}

Next, you want to move towards a walkable location near it.
Code:
var ctmterr = await Coroutines.ClickToMoveTo(mapDevice.WalkablePosition());
Log.DebugFormat("[Execute] ClickToMoveTo returned {0}.", ctmterr);

Now that you are close to it, you want to interact with it to open the map device window.
Code:
while (!LokiPoe.Gui.IsMapDeviceOpen)
{
   var iwoerr = await Coroutines.InteractWithObject(mapDevice.Id);
   Log.DebugFormat("[Execute] InteractWithObject returned {0}.", iwoerr);
   await Coroutine.Sleep(Utility.LatencySafeValue(1000));
}

Once the map window is open, you find your map in inventory, pick it up to the cursor, and place it somewhere in the map device.
Code:
var mapItem = LokiPoe.PlayerInventory.Main.FindItemByName("Tunnel Map");
if (mapItem == null)
{
// handle error
}

// This checks logical issues, not whether or not the item is actually picked up.
if (!mapItem.PickupToCursor())
{
// handle error
}
await Coroutine.Sleep(Utility.LatencySafeValue(1000)); // Let the server process the action.

// Check to make sure the cursor item is there.
var cursorItem = LokiPoe.PlayerInventory.Cursor.Items.FirstOrDefault();
if (cursorItem == null)
{
// handle error
}

// Try to move the map to a specified location in the device.
if (!cursorItem.MoveToMapDeviceTopLeft())
{
// handle error
}
await Coroutine.Sleep(Utility.LatencySafeValue(1000)); // Let the server process the action.

var deviceItem = LokiPoe.PlayerInventory.MapDevice.Items.FirstOrDefault();
if (deviceItem == null)
{
// handle error
}
// verify item(s)

At this point, your map is now in the device and you're ready to click the activate button (this will not work for you yet).
Code:
var res = await Coroutines.ClickControlCoroutine(() => LokiPoe.InGameState.CursorClient, LokiPoe.InGameState.ActivateMapDeviceButton);
Log.DebugFormat("[ResurrectToCheckpointCoroutine] ClickControlCoroutine returned {0}.", res);

If all goes well, your portals to the map are created. This is pretty much what our logic does in the generic coroutines. We don't have one for the map room yet, but we will soon enough when map logic is added to the bot we provide. If you wanted to write all your own code and not use any of our coroutines, that is the model you pretty much use; find the API that does each individual action, and do it. There's a lot of error handling and recovery to be done as we..

You can now use the object manager to find any of the new portals created, and take it. Once the bot is in the map, it now does the normal exploration / combat/ looting. What you'd probably need custom logic for, is maps that have 2nd floors or boss rooms you need to enter.

For the first half, it's just a matter of going to stash, withdraw the map item you want based on various settings, and if you wanted to get really fancy, you could do map rolling, but I'd worry about that later. Start with simple tasks to do each step, then integrate it all together. I'm not going to give a bunch of examples for that, but I think you should be able to work it out based on some other examples in this section or just looking through the coroutines and API. If you try something and can't get it working, please feel free to ask for help, but we just can't write everything for you. :)

I would recommend a separate bot implementation for maps. You don't have to worry about quests, waypoints, and a lot of other logic that gets in the way otherwise. You can more easily fine tune a new explorer to work better for the areas generated by maps, and of course make more map specific mod handling. I'm pretty sure that's the approach we'll be taking for map support, just make another bot with its own settings dedicated for maps. That way, things are a lot more maintainable, and special logic for maps won't interfere with the normal bot stuff.

Anyways, the new Beta setup definitely makes this task a lot easier than it was before in Release. We will have some basic map support added to the bot we provide in Beta, but I'd still recommend trying some stuff on your own and learning the API so you can have things work the way you want them to (and then modify ours later on to make it better).
 
Moved to "Community Developer Forum".

Upon testing a few things when writing this post, I noticed an offset not currently used by the bot broke, so it will be updated soon to work again for the next version. Right now, you can't click the Activate button, because the logic needs to be updated for the current client version.

Thanks pushedx! Currently I have finished to check if there is map in inventory, if not, withdraw 1 map in stash.

I get stuck in the withdraw part (CR wanted to go to waypoint and plugin need stash...lol), but then I found your example of selling 3x same map to npc, in that post you said some behavior may not work in plugin and need to implement in bot, so I though (and had some tries) it may not able to open the stash and do withdraw in plugin, I am now planning to move code to Bot from Plugin.

However, before I go for it, I would like to try test the following things:
1. Can bot access plugins setting(maybe force get the setting file by absolute path)
2. Is that really need to implement all action in bot.

===
I would like to always announce my process in this post :D And I also like to finish the open map device part in this week since the activate button can't press yet (and maybe try to use moveCursorTo() and ClickCursor() to activate it, I believe I have seen the first function in the .xml file, but not really remember the second one:))
 
I get stuck in the withdraw part (CR wanted to go to waypoint and plugin need stash...lol), but then I found your example of selling 3x same map to npc, in that post you said some behavior may not work in plugin and need to implement in bot, so I though (and had some tries) it may not able to open the stash and do withdraw in plugin, I am now planning to move code to Bot from Plugin.

The CR just handles combat related tasks (unless you use a bot that calls into Logic with other things) as well as bot specific logic overrides. While the bot is now setup to allow external Pois, you still have to do a bit of work to implement map logic in a way that doesn't interfere with normal non-map logic.

I would not recommend trying to add map support to ExilebuddyBot, because to do that, you need to rework several of our Pois as map logic inherently interferes with normal bot logic. That is why doing it in a new bot implementation would be much easier, and require less logic overall.

As for the withdrawing process, there's a neatly wrapped WithdrawItemsCoroutine that you can use to withdraw items from stash that meet certain criteria. You just have to implement a few simple user functions to filter the items and quantity (not applicable to maps) and that's all there is really. There's an example of using guild stash in the comments of ExampleBot, but you pretty much just use the non-guild version instead.

1. Can bot access plugins setting(maybe force get the setting file by absolute path)

In Beta #830, I added Configuration.Settings which allows users to see all registered settings, but they are the base settings type. You'd have to strongly type cast them against other code when compiling to actually change anything. So to answer your question, it's possible, but bad design.

Instead, the bot should expose settings plugins can change, then the plugins can simply change those values rather than the other way around. The same is still true when it comes to actually changing settings themselves, you need to reference the actual bot settings type to change anything.

2. Is that really need to implement all action in bot.

No, but it helps a lot to get started and something working. The more modular and weakly coupled your design is, the more complicated it can become managing all the parts and trying to fix conflicts between different parts of the system. For example, for ExilebuddyBot, we have a global BotState that a lot of the Pois have to reference and set data in, because otherwise, there's no clean way to manage the interactions between Pois other than setting the data directly in the current Poi instance (which would be bad if the user replaces the Poi, and there is other logic depending on those settings).

So, while the new design does give more flexibility and freedom, there is still a cost to trying to simply tack on new features to existing code when you did not originally design around it. That is why new features stopped being added to Release, trying to work them in with the code that was there was getting too unmanageable and harder each time.

I would like to always announce my process in this post :D And I also like to finish the open map device part in this week since the activate button can't press yet (and maybe try to use moveCursorTo() and ClickCursor() to activate it, I believe I have seen the first function in the .xml file, but not really remember the second one:))

Beta #830 was just built to fix those issues I mentioned in my post. If you check ExampleBot.cs now, there's some commented out code for opening the map device as well as clicking the Activate button. The coroutine for placing maps or fragments into various locations is not wrapped yet, but I'll get one added later along with a few other things that would be nice (one for selling, for example). They all use the same concepts, iso t's just a matter of writing and testing the logic. For now, the API should be working properly to do the task as I originally mentioned.
 
Back
Top