-
Notifications
You must be signed in to change notification settings - Fork 75
/
osrs_walker.py
267 lines (235 loc) · 10.1 KB
/
osrs_walker.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
import random
import subprocess
import time
import win32gui
import pyautogui
from time import sleep
import math
import json
from osrs_return_data_status import update_run_energy
from read_path import get_current_path, get_current_path_random
import yaml
with open("pybot-config.yaml", "r") as yamlfile:
data = yaml.load(yamlfile, Loader=yaml.FullLoader)
client_title = data[0]['Config']['client_title']
class Walking():
degreesPerYaw: float = 360 / 2048
def __init__(
self,
client_top_border: int,
client_side_border: int,
tiles_pixels: int,
offset_minimap_x: float,
offset_minimap_y: float,
offset_minimap_x_resize: float,
offset_minimap_y_resize: float,
offset_run_button_x: float,
offset_run_button_y: float,
offset_logout_x: float,
offset_logout_y: float
):
self.client_top_border = client_top_border
self.client_side_border = client_side_border
self.tiles_pixels = tiles_pixels
self.offset_minimap_x = offset_minimap_x
self.offset_minimap_y = offset_minimap_y
self.offset_minimap_x_resize = offset_minimap_x_resize
self.offset_minimap_y_resize = offset_minimap_y_resize
self.offset_run_button_x = offset_run_button_x
self.offset_run_button_y = offset_run_button_y
self.offset_logout_x = offset_logout_x
self.offset_logout_y = offset_logout_y
self.run_bool = False
def get_run_button(self, window_features: list) -> list:
x, y, w, h = window_features
run_x = x + (w - self.offset_run_button_x)
run_y = y + self.offset_run_button_y
return [run_x, run_y]
def get_logout_cross(self, window_features: list) -> list:
x, y, w, h = window_features
run_x = x + (w - self.offset_logout_x)
run_y = y + self.offset_logout_y
return [run_x, run_y]
def get_window(self, windowname: str) -> list:
'''Returns the position of the window and the size of the window excluding the borders.'''
# Get window handle.
hwnd = win32gui.FindWindow(None, windowname)
# Set window to foreground.
win32gui.SetForegroundWindow(hwnd)
# Get the window size.
rect = win32gui.GetWindowRect(hwnd)
# Adjust size for borders
x = rect[0]
y = rect[1] + self.client_top_border
w = rect[2] - x - self.client_side_border
h = rect[3] - y - self.client_top_border
return [x, y, w, h]
def find_center_minimap_resizable(self, window_features: list) -> list:
'''Returns the center of the window, excluding the borders.'''
x, y, w, h = window_features
map_center_x = x + (w - self.offset_minimap_x_resize)
map_center_y = y + self.offset_minimap_y_resize
return [map_center_x, map_center_y]
def get_live_info(self, category: str) -> dict:
'''Returns specific live information from the game client via the Status Socket plugin.'''
try:
f = open('live_data.json', )
data = json.load(f)
return data[category]
except:
pass
def compute_tiles(self, live_x: int, live_y: int, new_x: int, n_y: int) -> list:
'''Returns the range to click from the minimap center in amount of tiles.'''
# Get live camera data.
camera_data = self.get_live_info('camera')
print("camera data:", camera_data)
while camera_data is None:
camera_data = self.get_live_info('camera')
if camera_data != None:
# Get camera angle.
yaw = camera_data['yaw']
# Account for anticlockwise OSRS minimap.
degrees = 360 - self.degreesPerYaw * yaw
# Turn degrees into pi-radians.
theta = math.radians(degrees)
# Turn position difference into pixels difference.
x_reg = (new_x - live_x) * self.tiles_pixels
y_reg = (live_y - n_y) * self.tiles_pixels
# Formulas to compute norm of a vector in a rotated coordinate system.
tiles_x = x_reg * math.cos(theta) + y_reg * math.sin(theta)
tiles_y = -x_reg * math.sin(theta) + y_reg * math.cos(theta)
return [round(tiles_x, 1), round(tiles_y, 1)]
return [live_x, live_y]
def change_position(self, center_mini: list, live_pos: list, new_pos: list):
'''Clicks the minimap to change position'''
tiles = self.compute_tiles(live_pos[0], live_pos[1], new_pos[0], new_pos[1])
print("x:", center_mini[0] + tiles[0], "y:", center_mini[1] + tiles[1])
print("y1:", center_mini[1], "y2:", tiles[1])
pyautogui.click(center_mini[0] + tiles[0], center_mini[1] + tiles[1])
#self.walking_wait(new_pos[0], new_pos[1])
self.walking_wait_forgive(new_pos[0], new_pos[1])
def walking_wait(self, new_x: int, new_y: int):
'''Wait until finished walking.'''
position_data = self.get_live_info('worldPoint')
live_x, live_y = position_data['x'], position_data['y']
while live_x != new_x or live_y != new_y:
print(f"hasn't reach next point...current position ({live_x},{live_y}) next target ({new_x},{live_y})" )
position_data = self.get_live_info('worldPoint')
if position_data == None:
live_x, live_y = live_x, live_y
else:
live_x, live_y = position_data['x'], position_data['y']
continue
def walking_wait_forgive(self, new_x: int, new_y: int):
'''Wait until finished walking.'''
t_end = time.time() + random.randrange(10, 15)
position_data = self.get_live_info('worldPoint')
while position_data is None:
position_data = self.get_live_info('worldPoint')
live_x, live_y = position_data['x'], position_data['y']
while abs(new_x - live_x) > 2 or abs(new_y - live_y) > 2:
if time.time() > t_end:
print(time.time(), "| ", t_end)
break
time.sleep(0.1)
print(f"hasn't reach next point...current position ({live_x},{live_y}) next target ({new_x},{live_y})" )
position_data = self.get_live_info('worldPoint')
print("position_data:", position_data)
while position_data == None:
position_data = self.get_live_info('worldPoint')
if position_data == None:
live_x, live_y = live_x, live_y
else:
live_x, live_y = position_data['x'], position_data['y']
continue
def turn_run_on(self) -> None:
"""Turns on run energy."""
window = self.get_window(client_title)
run_on = self.get_run_button(window)
x = run_on[0] + random.randrange(-3, 3)
y = run_on[1] + random.randrange(-3, 3)
pyautogui.moveTo(x,y, duration = 0.2)
pyautogui.click()
def handle_running(self) -> None:
"""Turns on run if run energy is higher than 60."""
# If run is off and run energy is larger than 60, turn on run.
run_energy = update_run_energy()
while run_energy is None:
run_energy = update_run_energy()
run_energy = update_run_energy()
print(run_energy)
if run_energy < 5 or run_energy == 100:
self.run_bool = False
if run_energy > 60 and self.run_bool == False:
self.turn_run_on()
self.run_bool = True
def walk(self, path):
'''Walks a path by clicking on the minimap'''
window = self.get_window('OpenOSRS')
center_minimap = self.find_center_minimap_resizable(window)
pyautogui.moveTo(center_minimap)
# center_window = self.find_center_window(window)
# center_minimap = self.get_center_minimap(center_window)
path = path
position_data = self.get_live_info('worldPoint')
print(position_data)
while position_data is None:
position_data = self.get_live_info('worldPoint')
live_pos = [position_data['x'], position_data['y']]
new_pos = path[0]
# Walk while path has coordinates.
while path:
new_pos = path[0]
print(f'target: ({new_pos[0]},{new_pos[1]})')
# Turn on running if needed
#self.handle_running()
self.change_position(center_minimap, live_pos, new_pos)
# Wait for the map to catch up with live position.
sleep(2)
# Update position data.
position_data = self.get_live_info('worldPoint')
while position_data == None:
sleep(0.05)
position_data = self.get_live_info('worldPoint')
live_pos = position_data['x'], position_data['y']
print(f'current: ({live_pos[0]},{live_pos[1]})')
# Remove first coordinate.
path.pop(0)
#Paths = get_current_path()
Paths = get_current_path_random()
client_top_border = 30
client_side_border = 50
tiles_pixels = 4
offset_minimap_x = 377.0
offset_minimap_y = 195.0
offset_minimap_x_resize = 72
offset_minimap_y_resize = 81
offset_run_button_x = 150
offset_run_button_y = 130
offset_logout_x = 10
offset_logout_y = 10
walker = Walking(client_top_border,
client_side_border,
tiles_pixels,
offset_minimap_x,
offset_minimap_y,
offset_minimap_x_resize,
offset_minimap_y_resize,
offset_run_button_x,
offset_run_button_y,
offset_logout_x,
offset_logout_y
)
client_top_border = 30
client_side_border = 50
tiles_pixels = 4
offset_minimap_x = 377.0
offset_minimap_y = 195.0
offset_minimap_x_resize = 72
offset_minimap_y_resize = 81
offset_run_button_x = 150
offset_run_button_y = 130
offset_logout_x = 10
offset_logout_y = 10
degreesPerYaw: float = 360 / 2048
walker.walk(Paths)