-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathpathing.py
180 lines (153 loc) · 5.34 KB
/
pathing.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
import logging
from math import copysign, sqrt
import memory.main
import xbox
logger = logging.getLogger(__name__)
FFXC = xbox.controller_handle()
def set_movement(target) -> bool:
if memory.main.menu_open():
FFXC.set_neutral()
xbox.tap_a()
player = memory.main.get_coords()
(forward, right) = memory.main.get_movement_vectors()
# Calculate forward and right directions relative to camera space
pX = player[0]
pY = player[1]
eX = target[0]
eY = target[1]
fX = forward[0]
fY = forward[1]
rX = right[0]
rY = right[1]
Ly = fX * (eX - pX) + rX * (eY - pY)
Lx = fY * (eX - pX) + rY * (eY - pY)
sums_up = abs(Lx) + abs(Ly)
if sums_up == 0:
sums_up = 0.01
Lx /= sums_up
Ly /= sums_up
if abs(Lx) > abs(Ly):
Ly = copysign(Ly / Lx if Lx else 0, Ly)
Lx = copysign(1, Lx)
elif abs(Ly) > abs(Lx):
Lx = copysign(Lx / Ly if Ly else 0, Lx)
Ly = copysign(1, Ly)
else: # Only occurs on perfect diagonals.
Lx = copysign(1, Lx)
Ly = copysign(1, Ly)
FFXC.set_movement(Lx, Ly)
if memory.main.get_actor_id(0) == 20531:
d = 10
else:
d = 3
if abs(player[1] - target[1]) < d and abs(player[0] - target[0]) < d:
return True # Checkpoint reached
else:
return False
def distance(actor_index: int):
# Assume index is passed in.
actor_coords = memory.main.get_actor_coords(actor_index=actor_index)
player_coords = memory.main.get_actor_coords(actor_index=0)
distance = sqrt(
((player_coords[0] - actor_coords[0]) ** 2)
+ ((player_coords[1] - actor_coords[1]) ** 2)
)
return int(distance)
def distance_coords(target_coords):
# Assume x/y coords are passed as array.
player_coords = memory.main.get_actor_coords(actor_index=0)
distance = sqrt(
((player_coords[0] - target_coords[0]) ** 2)
+ ((player_coords[1] - target_coords[1]) ** 2)
)
return int(distance)
def approach_actor_by_index(actor_index: int, talk: bool = True):
return _approach_actor(actor_index=actor_index, talk=talk)
def approach_actor_by_id(actor_id: int, talk: bool = True):
index = memory.main.actor_index(actor_num=actor_id)
return _approach_actor(actor_index=index, talk=talk)
def approach_party_member(target_char, talk: bool = True):
index = target_char.actor_id
return approach_actor_by_id(actor_id=index, talk=talk)
def _approach_actor(actor_index: int = 999, talk: bool = True):
# This function can be called with either the actor ID or the actor index.
# The actor ID is not the same as their usual character ID like 0-6 for the party,
# but rather the ID used for the actor information in the game files.
logger.debug(f"Actor index {actor_index}")
speed_val = memory.main.get_game_speed()
if speed_val != 0:
memory.main.set_game_speed(0)
actor_coords = memory.main.get_actor_coords(actor_index=actor_index)
target_coords = [actor_coords[0], actor_coords[1]]
logger.debug(f"Actor's coordinates: {target_coords}")
logger.debug(f"Control: {memory.main.user_control()} | Naming: {memory.main.name_aeon_ready()}")
while (
memory.main.user_control()# or
#not memory.main.name_aeon_ready()
):
set_movement(target_coords)
if talk and distance(actor_index) < 15:
xbox.tap_b()
actor_coords = memory.main.get_actor_coords(actor_index=actor_index)
target_coords = [actor_coords[0], actor_coords[1]]
if memory.main.get_story_progress() < 20 and memory.main.name_aeon_ready():
FFXC.set_neutral()
return True
FFXC.set_neutral()
if speed_val != 0:
memory.main.set_game_speed(speed_val)
return True
def approach_coords(target_coords, diag:int = 999, click_through:bool = True):
speed_val = memory.main.get_game_speed()
if speed_val != 0:
memory.main.set_game_speed(0)
if diag != 999:
logger.debug(f"Moving until dialog value achieved: {diag}")
while memory.main.diag_progress_flag() != diag:
if memory.main.user_control():
set_movement(target_coords)
if distance_coords(target_coords) < 20:
xbox.tap_b()
elif memory.main.diag_skip_possible():
xbox.tap_b()
else:
while memory.main.user_control():
set_movement(target_coords)
if distance_coords(target_coords) < 20:
xbox.tap_b()
if speed_val != 0:
memory.main.set_game_speed(speed_val)
if click_through:
FFXC.set_neutral()
memory.main.click_to_control()
# TODO: Doesn't appear to be used, but left for historical purposes
def seymour_natus(): # First checkpoint ever written. :D
x = 15
y = 150
return [x, y]
# TODO: This appears to be unused. Was for a showcase in 2021.
def t_plains_dodging(checkpoint):
x = 999
y = 999
if checkpoint == 0:
x = 29
y = 149
if checkpoint == 1:
x = 16
y = -59
if checkpoint == 2:
x = 115
y = -297
if checkpoint == 3:
x = 35
y = -616
if checkpoint == 4:
x = -91
y = -866
if checkpoint == 5:
x = -121
y = -1089
if checkpoint == 6:
x = -120
y = -1300
return [x, y]