Multiple Targets in a row

Hi

iam new here and try to learn elm

Here i want to make a DecisionPathNode with several followingSteps.
But it fills not the list.

myWrecks =
                overviewWreckEntries 
                    |> List.map
                        (\overViewWreckEntry ->
                           test ++ [ ( " Lock a Target ", always (overViewWreckEntry.uiNode |> clickOnUIElement MouseButtonLeft |> Just ) ) ]
                        )

case No Wrecks all ok
case one Wreck all ok
case multiple wrecks only the first wreck will be targeted

ensureIsAtWreckingSiteAndTargetWreck : BotDecisionContext -> DecisionPathNode
ensureIsAtWreckingSiteAndTargetWreck context =
case context.parsedUserInterface |> overviewWindowEntriesRepresentingWrecks of
    [] ->
        DescribeBranch "I see no wrecks in the overview."  
            (EndDecisionPath Wait)
        
    [wreckInOverview] ->
        DescribeBranch
            ("Choosing wreck '" ++ (wreckInOverview.objectName |> Maybe.withDefault "Nothing") ++ "'")
            (lockTargetFromOverviewEntryAndEnsureIsInRange defaultBotSettings.attackMaxRange wreckInOverview)
        
    overviewWreckEntries -> 
        let   
            test = []

            myWrecks =
                overviewWreckEntries 
                    |> List.map
                        (\overViewWreckEntry ->
                           test ++ [ ( " Lock a Target ", always (overViewWreckEntry.uiNode |> clickOnUIElement MouseButtonLeft |> Just ) ) ]
                        )

            wrecks2Target = test ++ [ ( "Use keyboard key 'CTRL' to begin targeting. Key up.", always (VolatileHostInterface.KeyUp keyCodeLetterCTRL |> Just)) ]

        in 
            DescribeBranch ("Choosing multiple wrecks. ( " ++ (wrecks2Target |> List.length |> String.fromInt) ++ " || " ++ (test |> List.length |> String.fromInt)  ++ " )")
                (EndDecisionPath 
                     (Act
                        { firstAction = VolatileHostInterface.KeyDown keyCodeLetterCTRL 
                        , followingSteps = wrecks2Target
                        } 
                    )
                )    

overviewWindowEntriesRepresentingWrecks : ParsedUserInterface -> List OverviewWindowEntry
overviewWindowEntriesRepresentingWrecks =
.overviewWindow
    >> maybeNothingFromCanNotSeeIt
    >> Maybe.map (.entries >> List.filter overviewWindowEntryRepresentsAnWreck)
    >> Maybe.withDefault []


overviewWindowEntryRepresentsAnWreck : OverviewWindowEntry -> Bool
overviewWindowEntryRepresentsAnWreck entry =
    entry.textsLeftToRight |> List.any (String.toLower >> String.contains "wreck")

can someone suggest me a way to make such Lists ?

Sincerly Tea

Welcome Tea!

To make a valid list for followingSteps, we need to know its type.
Using a text search in the bot code, I find this:

Here we see the list element type is a tuple. The first element of the tuple is a string to display in the UI for this step. The second element is a bit more complex, it is this function: ParsedUserInterface -> Maybe VolatileHostInterface.EffectOnWindowStructure

The parameter is there because we get a new reading from the game client before each step.
The Nothing value of the return type is used to signal that the step failed. In this case, the whole sequence of steps is aborted.

Considering what we learned about the type above, the simplest way to make such a list of several followingSteps is this:

[ ("", always Nothing), ("", always Nothing) ]

(The always function returns a function that takes one parameter of any type and returns the argument given to always)

Let’s look how followingSteps is used in practice. Using text search again, I find this example:

This contains only one element, but since it is a list, you can add as many as you want.
Here is another example with three followingSteps:

Danke dir Viir

i have found a possible solution for my first problem.

A human dont klick every target step by step,

a Human press CTRL klick target 1 2 3 4 5 6 7 … and release the CTRL button.

i testet such script now and it is seems functional

ensureIsAtWreckingSiteAndTargetWreck : BotDecisionContext -> DecisionPathNode
ensureIsAtWreckingSiteAndTargetWreck context =
	case context.parsedUserInterface |> overviewWindowEntriesRepresentingWrecks of
		[] ->
			DescribeBranch "I see no Wrecks in the overview."  {- Dronen reinholen / Afterburner aus-}
				(EndDecisionPath Wait)
			
		[wreckInOverview] ->
			DescribeBranch
				("Choosing wreck '" ++ (wreckInOverview.objectName |> Maybe.withDefault "Nothing") ++ "'")
				(lockTargetFromOverviewEntryAndEnsureIsInRange defaultBotSettings.attackMaxRange wreckInOverview)
			
		overviewWreckEntries -> 
			let   
				test = []

				myWrecks =
					overviewWreckEntries 
							|> List.map (\overViewWreckEntry ->
										test ++ [ ( " Lock a Target ", always (overViewWreckEntry.uiNode |> clickOnUIElement MouseButtonLeft |> Just ) ) ]
										)
   
				wrecks2Target = (myWrecks |> List.concat) ++ [ ( "Use keyboard key 'CTRL' to begin targeting. Key up.", always (VolatileHostInterface.KeyUp keyCodeLetterCTRL |> Just)) ]

			in 
				DescribeBranch ("Choosing multiple wrecks. ( " ++ (wrecks2Target |> List.length |> String.fromInt) ++ " )")
					(EndDecisionPath 
						 (Act
							{ firstAction = VolatileHostInterface.KeyDown keyCodeLetterCTRL 
							, followingSteps = wrecks2Target
							} 
						)
					)    

overviewWindowEntriesRepresentingWrecks : ParsedUserInterface -> List OverviewWindowEntry
overviewWindowEntriesRepresentingWrecks =
	.overviewWindow
		>> maybeNothingFromCanNotSeeIt
		>> Maybe.map (.entries >> List.filter overviewWindowEntryRepresentsAnWreck)
		>> Maybe.withDefault []


overviewWindowEntryRepresentsAnWreck : OverviewWindowEntry -> Bool
overviewWindowEntryRepresentsAnWreck entry =
	entry.textsLeftToRight |> List.any (String.toLower >> String.contains "wreck")

Such script snippet can be used for ratting too, to divide the PVE Targets (first friggates, then cruiser size , and last Battleships)

This here was my fault: List in List and not the temp variable test like above.

wrecks2Target = (myWrecks |> List.concat) ++ [ (  

Next i need the filter function for targeting only my max possible activ targets.
Atm it try to target all visilble wrecks.

Thx i will try to understand more of elm :slight_smile:

Tea

1 Like

Sounds like List.take will do that: overviewWreckEntries |> List.take maxPossibleActivTargets

Danke

with that suggestion i could complete it

wrecks2Target = 
                (myWrecks |> List.concat |> List.take (defaultBotSettings.maxTargetCount - (context.parsedUserInterface.targets |> List.length)) ) ++ 
                [ ( "Use keyboard key 'CTRL' to begin targeting. Key up.", always (VolatileHostInterface.KeyUp keyCodeLetterCTRL |> Just)) ]

One problem closed

Greets Tea