Would this work like I think it does? String search in moduleButton.uiNode

Would this function and call effectively let me search for this text? I want to search for “Turn Off Overload” to know if the module is currently overloaded.

image

case getDescendantWithDisplayText "Turn Off Overload" moduleButton.uiNode of
    Nothing ->
        describeBranch
            ("Did not find the node with display text Turn Off Overload. Activate overload.")
                activateOverload

    Just _ ->
        describeBranch
            ("Module already overloaded. Will turn off when enemies are gone.")
                waitForProgressInGame
getDescendantWithDisplayText : String -> UIElement -> Maybe UIElement
getDescendantWithDisplayText displayText parent =
    parent
        |> EveOnline.ParseUserInterface.listDescendantsWithDisplayRegion
        |> List.filter (.uiNode >> EveOnline.ParseUserInterface.getDisplayText >> (==) (Just displayText))
        |> List.head

I actually cannot find a valid UIElement argument to test it

Ok I think I"m closer with this function.

overloadTank : ReadingFromGameClient -> Maybe DecisionPathNode
overloadTank readingFromGameClient =
    readingFromGameClient.shipUI
        |> Maybe.andThen
            (\shipUI ->
                case getDescendantWithDisplayText "Turn Off Overload" shipUI.uiNode of
                    Nothing ->
                        Just
                            (endDecisionPath
                                (actWithoutFurtherReadings
                                    ( "OVERLOADING TANKING MODULES FOR INCOMING GANK"
                                    , EffectOnWindow.effectsMouseClickAtLocation EffectOnWindow.MouseButtonLeft
                                        { x = 500
                                        , y = 400
                                        }
                                        ++ [ EffectOnWindow.KeyDown EffectOnWindow.vkey_P
                                           , EffectOnWindow.KeyUp EffectOnWindow.vkey_P
                                           ]
                                    )
                                )
                            )

                    Just _ ->
                        Nothing
            )

I think I fixed it.

Got it working! I think. I need to test ingame now.

Nope it is not detecting the “Turn Off Overload” string.

After looking in the memory log the tooltip does change to Turn Off Overload in memory.

I just need a way to search for the string located anywhere but ideally modulebuttons

I found this.

getHintTextFromDictEntries : EveOnline.MemoryReading.UITreeNode -> Maybe String
getHintTextFromDictEntries =
    getStringPropertyFromDictEntries "_hint"

Something like that perhaps.

shipModuleButtonRepresentsOverload : UITreeNodeWithDisplayRegion -> Bool
shipModuleButtonRepresentsOverload entry =
    if getHintTextFromDictEntries entry.uiNode == Just "Turn Off Overload" then
        True

    else
        False

I cannot figure it out.

This is my last function that I feel is closest to achieving what I want to do.

overloadTank : ReadingFromGameClient -> SeeUndockingComplete -> Maybe DecisionPathNode
overloadTank readingFromGameClient seeUndockingComplete =
    case seeUndockingComplete |> tankModulesToOverload |> List.head of
        Just moduleToOverload ->
            if tooltipLooksLikeOverloadedModule moduleToOverload == False then
                Just
                    (endDecisionPath
                        (actWithoutFurtherReadings
                            ( "OVERLOADING TANKING MODULES FOR INCOMING GANK - inside overloadTank"
                            , EffectOnWindow.effectsMouseClickAtLocation EffectOnWindow.MouseButtonLeft
                                { x = 500
                                , y = 400
                                }
                                ++ [ EffectOnWindow.KeyDown EffectOnWindow.vkey_P
                                   , EffectOnWindow.KeyUp EffectOnWindow.vkey_P
                                   ]
                            )
                        )
                    )

            else
                Just (describeBranch "Already overloaded." waitForProgressInGame)

        Nothing ->
            Just (describeBranch "Modules not found" waitForProgressInGame)
tankModulesToOverload : SeeUndockingComplete -> List EveOnline.ParseUserInterface.ShipUIModuleButton
tankModulesToOverload =
    .shipUI >> .moduleButtonsRows >> .middle 
tooltipLooksLikeOverloadedModule : EveOnline.ParseUserInterface.ShipUIModuleButton -> Bool
tooltipLooksLikeOverloadedModule =
    .slotUINode
        >> .uiNode
        >> getAllContainedDisplayTexts
        >> List.any
            (Regex.fromString "\\s*Off\\s*" |> Maybe.map Regex.contains |> Maybe.withDefault (always False))

Looking at the rectangle that you put in the screenshot: The name left of the equals sign should be useful to filter the properties to get the one you highlighted.

That looks interesting. Does that work?

I was not able to provide a valid EveOnline.MemoryReading.UITreeNode to point at modulebuttons.

That’s why I looked for another way with more accessible entries. Like ShipUIModuleButtons

I don’t understand how to feed the proper value to getHintTextFromDictEntries.

I GOT IT!

Added a function in ParseUserInterface

getDisplayHint : EveOnline.MemoryReading.UITreeNode -> Maybe String
getDisplayHint uiNode =
    [ "_hint", "_hint" ]
        |> List.filterMap
            (\displayTextPropertyName ->
                uiNode.dictEntriesOfInterest
                    |> Dict.get displayTextPropertyName
                    |> Maybe.andThen (Json.Decode.decodeValue Json.Decode.string >> Result.toMaybe)
            )
        |> List.sortBy (String.length >> negate)
        |> List.head

Added a function in BotEngineApp

getDescendantWithDisplayHint : String -> UIElement -> Maybe UIElement
getDescendantWithDisplayHint displayText parent =
    parent
        |> EveOnline.ParseUserInterface.listDescendantsWithDisplayRegion
        |> List.filter (.uiNode >> EveOnline.ParseUserInterface.getDisplayHint >> (==) (Just displayText))
        |> List.head

displayText = “Turn Off Overload”

This let me know when overload is on. It’s not precise but if 1 of my module is overloaded all of them should be.

You can use the Find All References function in the code editor on any reference to the type EveOnline.MemoryReading.UITreeNode. The editor then displays a list of all references to that type. This way you can navigate to the sources of values of this type.

This way, you find that EveOnline.ParseUserInterface.UITreeNodeWithDisplayRegion has one in the field uiNode.
EveOnline.ParseUserInterface.UITreeNodeWithDisplayRegion is a popular type to model parts of the UI because when we know the display region we can interact with the element using the mouse cursor.

You can do the references search for that type, which yields around 174 references in the latest framework.

In these search results, there are also these two:

  • listChildrenWithDisplayRegion → get the children of a UI node.
  • listDescendantsWithDisplayRegion → get all descendants in a list. The number of elements is the same that is displayed in the alternate UI tree explorer that you showed in your screenshot above. When you find a node as a descendant in that tree explorer, you can get it via listDescendantsWithDisplayRegion.

Here you can see the search results also show how to get there starting from a ship module button:
image

You can also see these fields leading to the UI nodes in the screenshot you posted.

In the screenshot you posted, you expanded the ‘children’ of a node. To get these, use listChildrenWithDisplayRegion.