(Note: A bot is a program that automates stuff, in this case various actions in a game, such s moving or crafting items)
Hi! My curiosity towards vb.net is showing it's head again, this time I decided to try and make some fairly simple bots for EverQuest 2. First, I made a bot that crafts items based on whatever item names someone adds to a datagridview. It works great, but it's completely working by color codes, no memory is read/written at all.
Now, I want to create a leveling bot that basically follows coordinates and attacks / kills all pre-defined creatures on the way. This, of course, wouldn't work by using color codes (plus that's boring!) I started by retrieving the coordinates from the game's memory and created a way in my vb.net app to save them to a listbox.
After hitting the start button, the following happens:
1. The bot determines how much further forward/back it must go on the Y-coordinate
2. Then it determines the same thing for X-coordinates
The way it does this is spot the difference between the current coordinates, and the coordinates defined in the listbox. And also if it's a negative number or not. Negative means forward/strafe right, positive means backwards/strafe left. For this to work, we need to always be facing North, but I'll get to that issue once I get this working.
This presents me with two problems:
Problem 1 - Movement Logic
After finishing our path by inserting coordinates, We start by clicking the start button. (Sorry, I couldn't figure out how to highlight=vb.net )
Code:
Private Sub startButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles startButton.Click
statusLabel.Text = "Started"
For i = 0 To wpListBox.Items.Count - 1
Do Until worker1done = 1 'Wait for worker1 to finish
Application.DoEvents()
Loop
If worker1done = 1 Then worker1done = 0 : currentlbitem = i : BackgroundWorker1.RunWorkerAsync() 'Worker1 done? Go for next coordinates!
Next
End Sub
So worker1 starts doing it's thing:
Code:
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
AppActivate("Everquest II")
Dim gotoX As Single = 0
Dim gotoY As Single = 0
Dim gotoZ As Single = 0
Dim forward As Integer = 1
'Dim right As Integer = 1 'This is globally determined now so bgworker2 can use it.
Dim up As Integer = 1
'
'For now, just assume we start facing north
'
'Split current coords to X Y Z
Single.TryParse(wpListBox.Items.Item(currentlbitem ).Split(" ")(0), gotoX)
Single.TryParse(wpListBox.Items.Item(currentlbitem ).Split(" ")(1), gotoY)
Single.TryParse(wpListBox.Items.Item(currentlbitem ).Split(" ")(2), gotoZ)
'What way do we need to go?
If gotoY - currentY > 0 Then forward = 0 'We need to go backwards if Y needs to become bigger
If gotoX - currentX > 0 Then right = 0 'We need to go left when X needs to become bigger
If gotoZ - currentZ > 0 Then up = 0 'This isn't used yet.
'
'Strafe, don't release it until we are enough further.
'
If worker2done = 1 Then worker2done = 0 : gotoXglobal = gotoX : BackgroundWorker2.RunWorkerAsync()
Do Until worker2done = 1 'Wait for strafing to be completed
Application.DoEvents()
Loop
'
'Hit the W key, don't release it until we are enough further.
'
keybd_event(VK_W, 0, 0, 0) 'Press W down.
Do Until (forward = 1 And currentY <= gotoY) Or (forward = 0 And currentY >= gotoY) 'Move forward until we are enough (or more than) further backwards/forward
Application.DoEvents()
Loop
keybd_event(VK_W, 0, 2, 0) 'Release W
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
statusLabel.Text = "Stopped"
worker1done = 1 'Worker1 done.
End Sub
So in short, bgworker 1 starts bgworker2, bgworker2 strafes until the current coordinates are equal to or greater than where we want to be vertically (west/east). After that, bgworker 1 continues by holding down W until we walked far enough (north/south)
And here is the bgworker that handles strafing:
Code:
Private Sub BackgroundWorker2_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker2.DoWork
If right = 1 Then
keybd_event(VK_E, 0, 0, 0) 'E for right
End If
If right = 0 Then
keybd_event(VK_Q, 0, 0, 0) 'Q for left
End If
If right = 1 Then
Do Until (right = 1 And currentX <= gotoXglobal) 'Wait until have strafed far enough right
Application.DoEvents()
Loop
End If
If right = 0 Then
Do Until (right = 0 And currentX >= gotoXglobal) 'Wait until have strafed far enough left
Application.DoEvents()
Loop
End If
If right = 1 Then
keybd_event(VK_E, 0, 2, 0) 'Release E
End If
If right = 0 Then
keybd_event(VK_Q, 0, 2, 0) 'Release Q
End If
End Sub
Private Sub BackgroundWorker2_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker2.RunWorkerCompleted
worker2done = 1
End Sub
Problem? This doesn't work that well. I made a short vid where I 1. create the waypoints, 2. Run back and let the bot follow them
Problem 2 - VirtualKeys suck!
Ideally I want the keys to be sent directly to the game, rather than emulating an actual keypress. That would make the bot work while I could do other stuff. That's truelly ideally though, I really just want to get rid of VKeys because they're not working all that well. SendKeys was even worse though!
Please note I don't expect anyone to do the dirty work for me. I just *know* that there are way (yes that deserves bolding!) better methods out there than whatever the hell I am coming up with atm. All I'm asking for is some help ;D Thanks!