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).