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 :
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.
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
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
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.
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;