|
You last visited: Today at 10:04
Advertisement
AutoIt help with while loop bot function
Discussion on AutoIt help with while loop bot function within the AutoIt forum part of the Coders Den category.
08/11/2017, 16:12
|
#1
|
elite*gold: 0
Join Date: Aug 2017
Posts: 11
Received Thanks: 0
|
AutoIt help with while loop bot function
Hi, i am creating a bot and i get stucked in one point of developing a bot.
Its my main loop function where i need to display some stuff on listview but i have problem because all is in while loop so it repeating few times always.
So what i need ?
I need to bot doing next in main loop:
- send tab to select mob ( add "searching mob" to list 1 time untill mob is found )
- if mob is selected and mob hp is greater than 0 send 3 to attack ( add "attacking mob" to list 1 time only untill attacking mob )
- when mob is dead add count +1 ( add "mob killed +1" to list 1 time when mob is dead )
repeat
At the moment it repeat and counting too many mobs, like i killed 2 he count 5 and work like :
searching mob
attacking mob
attacking mob
attacking mob
attacking mob
attacking mob
attacking mob
attacking mob
mobs killed 1
Code:
Func _start()
$run = Not $run
If $run = True Then
GUICtrlSetData($bot_status, "Bot running")
_GUICtrlListBox_InsertString($List1, _NowTime() & " : Bot started", 0)
Else
GUICtrlSetData($bot_status, "Bot paused")
_GUICtrlListBox_InsertString($List1, _NowTime() & " : Bot paused", 0)
EndIf
While $run = True
; get mob hp
$handles = _KDMemory_OpenProcess($processId)
$baseAddress = _KDMemory_GetModuleBaseAddress($handles, $moduleName) + $baseOffset
$memoryData = _KDMemory_ReadProcessMemory($handles, $baseAddress, "DWORD", $enemyHpOffset)
Local $pickPause = 300
#cs
send tab to select mob ( add "searching mob" to list 1 time untill mob is found )
if mob is selected and mob hp is greater than 0 send 3 to attack ( add "attacking mob" to list 1 time only untill attacking mob )
when mob is dead add count +1 ( add "mob killed +1" to list 1 time when mob is dead )
repeat ( repeat process )
#ce
; if mob hp is grater than zero send 3 to attack it
If $memoryData[1] > 0 Then
_GUICtrlListBox_InsertString($List1, _NowTime() & " : Attacking mob", 0)
ControlSend($title, "", "", "{3}")
Sleep(500)
Else
; send space after killing mob to pick items
_GUICtrlListBox_InsertString($List1, _NowTime() & " : Picking items", 0)
ControlSend($title, "", "", "{SPACE}")
Sleep($pickPause)
ControlSend($title, "", "", "{SPACE}")
Sleep($pickPause)
ControlSend($title, "", "", "{SPACE}")
Sleep($pickPause)
ControlSend($title, "", "", "{SPACE}")
Sleep($pickPause)
ControlSend($title, "", "", "{SPACE}")
Sleep($pickPause)
ControlSend($title, "", "", "{SPACE}")
Sleep($pickPause)
; send tab to select mob
_GUICtrlListBox_InsertString($List1, _NowTime() & " : Searching mob", 0)
ControlSend($title, "", "", "{TAB}")
; add +1 to mobs killied
$mobsKilled += 1
GUICtrlSetData($killedMobs, $mobsKilled)
_GUICtrlListBox_InsertString($List1, _NowTime() & " : Mobs killed - " & $mobsKilled, 0)
EndIf
; mob hp display
GUICtrlSetData($enemyHp, $memoryData[1])
_KDMemory_CloseHandles($handles)
WEnd
EndFunc
|
|
|
08/12/2017, 10:28
|
#2
|
elite*gold: 400
Join Date: Jun 2011
Posts: 513
Received Thanks: 101
|
This happens in a view milliseconds in case the mobs HP is < 0:
read memory > HP-If-Statement > MobCounter =+1
I think your script is faster than the Game. The mob isnt alreads deleted in game memory and u read the informations again.
Try to Sleep a view seconds before you searching or the next mob.
Btw.
I dont know if it is good or bad, but u set $pickPause always again. Maybe its better to put it above your While-Loop.
And you have 2 statements about $run, maybe you can connect them to 1 statement.
|
|
|
08/12/2017, 13:03
|
#3
|
elite*gold: 0
Join Date: Aug 2017
Posts: 11
Received Thanks: 0
|
Founded solution, i splited all in functions and now works better and accurate.
Added $pickTimes in global var
And now adding 1 time per action to list:
add "searching mob" 1 time -> searching mob ( sending TAB ) untill mob is founded
add "attacking mob" 1 time -> sending ( 3 ) untill mob hp is 0
add "picking items" 1 time -> pick drop -> send space few times
add mob kill +1
repeating !
Code:
; MAIN LOOP
Func _start()
; paused global
$run = Not $run
; add to list when bot is started/paused
If $run = True Then
_GUICtrlListBox_InsertString($List1, _NowTime() & " : Bot started", 0)
Else
_GUICtrlListBox_InsertString($List1, _NowTime() & " : Bot paused", 0)
EndIf
; MAIN LOOP
; while not paused
While $run = True
_findMob()
_attackMob()
_GUICtrlListBox_InsertString($List1, _NowTime() & " : Picking items", 0)
_pickItems()
WEnd
EndFunc
; get mob hp, return HP value
Func _getMobHP()
$handles = _KDMemory_OpenProcess($processId)
$baseAddress = _KDMemory_GetModuleBaseAddress($handles, $moduleName) + $baseOffset
$memoryData = _KDMemory_ReadProcessMemory($handles, $baseAddress, "DWORD", $enemyHpOffset)
Return $memoryData[1]
_KDMemory_CloseHandles($handles)
EndFunc
; set mob hp to gui
Func _mobHpToGUI()
If _getMobHP() > 0 Then
GUICtrlSetData($enemyHp, _getMobHP())
Else
GUICtrlSetData($enemyHp, "0")
EndIf
Sleep(500)
EndFunc
; find mob
Func _findMob()
; add to list
_GUICtrlListBox_InsertString($List1, _NowTime() & " : Searching mob", 0)
; send tab untill mob founded, mob hp grater than 0
Do
ControlSend($title, "", "", "{TAB}")
Sleep(500)
Until _getMobHP() > 0
; add to list
_GUICtrlListBox_InsertString($List1, _NowTime() & " : Attacking mob", 0)
EndFunc
; kill mob
Func _attackMob()
; send key 3 untill mob is dead
Do
ControlSend($title, "", "", "{3}")
Sleep(500)
Until _getMobHP() = 0 ; mob dead = 0
Sleep(100)
; add count +1
$mobsKilled += 1
Sleep(500)
; set data to mobs killed counter
GUICtrlSetData($killedMobs, $mobsKilled)
; add to list
_GUICtrlListBox_InsertString($List1, _NowTime() & " : Mobs killed - " & $mobsKilled, 0)
EndFunc
Func _myManaHp()
Local $handles = _KDMemory_OpenProcess($processId)
Local $hpAddress = _KDMemory_GetModuleBaseAddress($handles, $moduleName) + $currentHpBaseOffset
Local $hpFullAddress = _KDMemory_GetModuleBaseAddress($handles, $moduleName) + $baseOffset
Local $manaAddress = _KDMemory_GetModuleBaseAddress($handles, $moduleName) + $baseOffset
Local $manaFullAddress = _KDMemory_GetModuleBaseAddress($handles, $moduleName) + $baseOffset
Local $hpMemoryData = _KDMemory_ReadProcessMemory($handles, $hpAddress, "DWORD", $myHpOffset)
Local $hpFulllMemoryData = _KDMemory_ReadProcessMemory($handles, $hpFullAddress, "DWORD", $myFullHpOffset)
Local $manaMemoryData = _KDMemory_ReadProcessMemory($handles, $manaAddress, "DWORD", $myManaOffset)
Local $manaFullMemoryData = _KDMemory_ReadProcessMemory($handles, $manaFullAddress, "DWORD", $myFullManaOffset)
GUICtrlSetData($hp, $hpMemoryData[1] & " / " & $hpFulllMemoryData[1])
Sleep(100)
GUICtrlSetData($mana, $manaMemoryData[1] & " / " & $manaFullMemoryData[1])
Sleep(100)
_KDMemory_CloseHandles($handles)
Sleep(500)
EndFunc
; picking items, send space with pause between picks
Func _pickItems()
ControlSend($title, "", "", "{SPACE}")
Sleep($pickPause)
ControlSend($title, "", "", "{SPACE}")
Sleep($pickPause)
ControlSend($title, "", "", "{SPACE}")
Sleep($pickPause)
ControlSend($title, "", "", "{SPACE}")
Sleep($pickPause)
ControlSend($title, "", "", "{SPACE}")
Sleep($pickPause)
ControlSend($title, "", "", "{SPACE}")
Sleep($pickPause)
EndFunc
Func _end()
Exit
EndFunc
|
|
|
08/12/2017, 16:35
|
#4
|
elite*gold: 0
Join Date: Feb 2009
Posts: 1,137
Received Thanks: 573
|
Just as an advice, you could realize this in your program using a state machine. If you define a set of states your program can currently be in, and a set of viable transition. As your states have each only one successor it's a pretty trivial task:
Code:
Local $Transitions[4][3] = [["SearchState", "AttackState", "StartAttack"],["AttackState", "MobKilledState", "MobKilled"],["MobKilledState", "SearchState", "StartSearch"], ["InitState", "SearchState", "StartSearch"]]
func StartAttack()
; attacking code
; if worked corectly:
Return True
; otherwise return false
EndFunc
func MobKilled()
; mob got killed code
; if worked corectly:
Return True
; otherwise return false
EndFunc
func StartSearch()
; Searching code
; if worked corectly:
Return True
; otherwise return false
EndFunc
func nextState(ByRef $CurrentState)
For $i = 0 to UBound($Transitions, 1) - 1
If ($Transitions[$i][0] = $CurrentState) And (Call($Transitions[$i][2]) = True) Then
$CurrentState = $Transitions[$i][1]
Return
EndIf
Next
EndFunc
; Main Program:
$currState = "InitState"
While True
nextState($currState)
WEnd
If its more ambiguous, and a state could have multiple successors, you need to specify them, and use somekind of this function to transition:
Code:
func TransitState(ByRef $CurrentState, Const $NextState)
For $i = 0 to UBound($Transitions, 1) - 1
If ($Transitions[$i][0] = $CurrentState) And ($Transitions[$i][1] = $NextState) And (Call($Transitions[$i][2]) = True) Then
$CurrentState = $NextState
Return
EndIf
Next
EndFunc
State machines are easy to maintain and to extend, as also produce a very easy to understand code
|
|
|
08/12/2017, 17:05
|
#5
|
elite*gold: 0
Join Date: Aug 2017
Posts: 11
Received Thanks: 0
|
Quote:
Originally Posted by warfley
Just as an advice, you could realize this in your program using a state machine. If you define a set of states your program can currently be in, and a set of viable transition. As your states have each only one successor it's a pretty trivial task:
Code:
Local $Transitions[4][3] = [["SearchState", "AttackState", "StartAttack"],["AttackState", "MobKilledState", "MobKilled"],["MobKilledState", "SearchState", "StartSearch"], ["InitState", "SearchState", "StartSearch"]]
func StartAttack()
; attacking code
; if worked corectly:
Return True
; otherwise return false
EndFunc
func MobKilled()
; mob got killed code
; if worked corectly:
Return True
; otherwise return false
EndFunc
func StartSearch()
; Searching code
; if worked corectly:
Return True
; otherwise return false
EndFunc
func nextState(ByRef $CurrentState)
For $i = 0 to UBound($Transitions, 1) - 1
If ($Transitions[$i][0] = $CurrentState) And (Call($Transitions[$i][2]) = True) Then
$CurrentState = $Transitions[$i][1]
Return
EndIf
Next
EndFunc
; Main Program:
$currState = "InitState"
While True
nextState($currState)
WEnd
If its more ambiguous, and a state could have multiple successors, you need to specify them, and use somekind of this function to transition:
Code:
func TransitState(ByRef $CurrentState, Const $NextState)
For $i = 0 to UBound($Transitions, 1) - 1
If ($Transitions[$i][0] = $CurrentState) And ($Transitions[$i][1] = $NextState) And (Call($Transitions[$i][2]) = True) Then
$CurrentState = $NextState
Return
EndIf
Next
EndFunc
State machines are easy to maintain and to extend, as also produce a very easy to understand code
|
Thanks man for advice, i am new in this kind of programing so any advice is useful for me.
I know bots are not easy to make because it require more actions to work, and as i see on many examples and read on many forums its not easy in AutoIt because it don't support multithreading and multitasking.
|
|
|
Similar Threads
|
std::function of a function returning an std::function
11/11/2013 - C/C++ - 19 Replies
Nun muss ich nach langer Zeit auch mal wieder einen Thread erstellen, weil mir Google nicht mehr weiterhelfen kann.
Ich verzweifle an Folgendem Vorhaben:
#include <Windows.h>
#include <string>
#include <iostream>
using namespace std;
|
[Free BOT] iBot (With loop function)
04/18/2010 - SRO Hacks, Bots, Cheats & Exploits - 12 Replies
#Removed
Sorry for this tread
|
All times are GMT +1. The time now is 10:05.
|
|