Need help with selecting items in inventory

I’ve been trying to learn and code a bot for myself but i’m running into some snags, specifically i cant seem to menurootclick on an item in my cargo hold. As is the code searches the inventory, but doesnt select the probes/right click show info correctly. For this code, i want to simply right click the remaining object after searching my cargo bay and show info. If you could also be so kind as to show me how to read the number of x object stored in my hold as well it would be greatly appreciated. Sorry for format im unsure how to do that.

    using BotSharp.ToScript.Extension;

using MemoryStruct = Sanderling.Interface.MemoryStruct;
using Parse = Sanderling.Parse;

Sanderling.Parse.IWindowInventory WindowInventory => Measurement?.WindowInventory?.FirstOrDefault();
var Measurement = Sanderling?.MemoryMeasurementParsed?.Value;
var ManeuverType = Measurement?.ShipUi?.Indication?.ManeuverType;

string ProbeName = “Sisters Core”;

ShowInfo();

void ShowInfo()
{
Sanderling.MouseClickLeft(WindowInventory?.InputText?.FirstOrDefault());
Sanderling.TextEntry(ProbeName);
var ShowItemInfo = WindowInventory?.SelectedRightInventory?.ListView?.Entry?.ToArray();
var ShowInfo = ShowItemInfo?.FirstOrDefault();
ClickMenuEntryOnMenuRoot(ShowInfo, “Show Info”);

}

void ClickMenuEntryOnMenuRoot(IUIElement MenuRoot, string MenuEntryRegexPattern)
{
Sanderling.MouseClickRight(MenuRoot);
var Menu = Measurement?.Menu?.FirstOrDefault();
var MenuEntry = Menu?.EntryFirstMatchingRegexPattern(MenuEntryRegexPattern, RegexOptions.IgnoreCase);
Sanderling.MouseClickLeft(MenuEntry);
}

The quickest way I see is to copy and adapt from the mining bot. The mining bot from the example projects already interacts with items in the inventory, using drag&drop on these. It also opens context menus, so it contains building blocks that are very close already to what you need.

Since I know the mining bot uses drag&drop, I can search the bot code for this operation to see where it reads the inventory item, and find this part: bots/Bot.elm at 3af6103a93a8a91d691f3fc15db45abf7203c827 · Viir/bots · GitHub

For the new use case, we need to adapt this to take not the first item but to filter for Sisters Core. We could use the filtering function in the game UI, but this would require an additional step of entering the text in the text box. An easier way is to filter the inventory items in our app code.

As long as you have set the inventory to List view mode, you will find the inventory items in the listViewItems field in the record representing the inventory.

We can do the filtering with this function:

inventoryWindowSelectedContainerMatchingItems : String -> ParsedUserInterface -> List UIElement
inventoryWindowSelectedContainerMatchingItems filterText parsedUserInterface =
    let
        itemMatchesFilter =
            .uiNode
                >> EveOnline.MemoryReading.getAllContainedDisplayTexts
                >> List.any (String.toLower >> String.contains (filterText |> String.toLower))
    in
    parsedUserInterface.inventoryWindows
        |> List.head
        |> Maybe.andThen .selectedContainerInventory
        |> Maybe.map (.listViewItems >> List.filter itemMatchesFilter)
        |> Maybe.withDefault []

This function takes two arguments:

  • The text to use for filtering.
  • The parsed user interface as we get it from the EVE Online framework.

I integrated this into a complete bot that displays the number of matching inventory items and also opens show info on a matching item.

To see the bot in action:

botengine  run-bot  "https://github.com/Viir/bots/tree/93d2b0cfd8e385e8b177dfc6b82bd9eb0c177723/implement/applications/eve-online/noxygenic-inventory"

And here you can see how the filtering function is integrated into the bot code to open show info:

The guide on working with the parsed user interface now also contains this section about the inventory window: https://github.com/Viir/bots/blob/master/guide/eve-online/parsed-user-interface-of-the-eve-online-game-client.md#inventory-window

It also covers how to get the items in the selected container.

Inventory items in the memory reading inspection tool

1 Like

Sorry I realize I should have clarified but i’m writing this in c#. Have no knowledge of the .elm format. I’ve been just writing in the development window in sanderling.exe/notepad++. When plugging the code you gave me it pulls a ton of errors and references elm based sanderling stuff. Is there any way to do something similar with c#?

In case this question is directed at me: Likely there is a way, but I don’t remember seeing a solution for C#.

1 Like

Hey @Noxygenic actually you have all the answers here and the end implementation is your choice.

WindowInventory?.FirstOrDefault().SelectedRightInventory?.ListView?.Entry

Here are all the items within your intentory and they are placed in rows like if you have 2 rows of items it will contains two items under it. The first row with index 0 and second row with index 1 (as usual).
I’m not totally sure what you want to count but if you want to check the humber in one cell like how much items you have in that pile. For first item in first row it will looks like this

WindowInventory?.FirstOrDefault().SelectedRightInventory?.ListView?.Entry
    .FirstOrDefault().LabelText?.FirstOrDefault().Text

This implementation have one problem is that Labels are placed in order where numbers first and then there is items names after all the numbers in that row but you can easily match them with mod (reminder after division) method.
Here is an example

Imgur

But if you want to count the cells with specific name such as “Probe” you need to run through all the labels and just count it. Something like this but its only for one row of inventory

WindowInventory?.FirstOrDefault().SelectedRightInventory?.ListView?.Entry
    .FirstOrDefault().LabelText?.Where(x => x.Text.Contains("Probe")).Count

I hope its helped.

2 Likes

@Viir Thanks for the help anyway. If i get into .elm ill take a look at that method you shared.

@TheChosenOne I seem to be having some problems with your method. To start off in your image you are seeing Sanderling.Interface.MemoryStruct.IListEntry[] (3rd line in). However i’m not seeing that. Im reading the inventory from Sanderling.Interface.MemoryStruct.WindowStack[] . I suspect its because you are using a different measurement then Sanderling.Interface.MemoryStruct.MemoryMeasurement (the original tree I am exploring from). Im not sure how to use your filter and see what your sanderling is seeing.

Second I plugged the code below in and it gave me this error. " ‘IWindowInventory’ does not contain a definition for ‘FirstOrDefault’ and no extension method ‘FirstOrDefault’ accepting a first argument of type ‘IWindowInventory’ could be found (are you missing a using directive or an assembly reference?)"

 WindowInventory?.FirstOrDefault().SelectedRightInventory?.ListView?.Entry
.FirstOrDefault().LabelText?.FirstOrDefault().Text

The Offending Portion is FirstOrDefault() just after WindowInventory?.
Putting those issues aside I did manage to Host.Log my probe count to see the number of probes i have. Some questions i have further are how to index labeltext[1] or [2] etc… All examples i’ve seen only show FirstOrDefault(); so i have no examples of this so far. And i also still would like to know how to left click an inventory object if you know how to do that.