diff --git a/bot.py b/bot.py index fb305bc..642c992 100644 --- a/bot.py +++ b/bot.py @@ -217,8 +217,11 @@ def padd(p1, p2): def psub(p1, p2): return (p1[0] - p2[0], p1[1] - p2[1], p1[2] - p2[2]) +def phyp(p1, p2): + return hypot(p1[0] - p2[0], p1[1] - p2[1], p1[2] - p2[2]) + def pint(p): - return (int(p[0]), int(p[1]), int(p[2])) + return (floor(p[0]), floor(p[1]), floor(p[2])) # larger started being slower BLOCK_CACHE_SIZE = 2**14 @@ -296,9 +299,6 @@ class MazeSolver(AStar): if not self.bair(padd(node, BLOCK_ABOVE2)): return False - if not self.bair(padd(dest, BLOCK_ABOVE2)): - return False - return True def check_descend(self, node, offset): @@ -346,6 +346,9 @@ class MazeSolver(AStar): if not self.check_ascend(node, offset): return False + if not self.bair(padd(dest, BLOCK_ABOVE2)): + return False + if not self.bair(padd(middle, BLOCK_ABOVE)): return False @@ -398,6 +401,7 @@ class MazeSolver(AStar): def spiral(n): # return x, 0, z coords along a spiral at step n + # I forget where I found this n += 1 k = ceil((sqrt(n)-1)/2) t = 2 * k + 1 @@ -442,6 +446,7 @@ def break_block(connection, coords, time): s['break_finished_packet'].face = 1 s['break_time'] = time + s['break_timeout'] = 0.25 BLOCK_ABOVE = (0, +1, 0) @@ -480,14 +485,21 @@ class MCWorld: if offset[0] > distance: return result - def find_tree(self, center, distance): + def find_trees(self, center, distance): logs = [] for i in range(5): - check = padd(center, alternate(i, 4)) - logs.extend(self.find_blocks(center, distance, blocks.LOG_IDS, 5)) + check = padd(center, alternate(i, 3)) + logs.extend(self.find_blocks(check, distance, blocks.LOG_IDS, 50)) + print(logs) + + trees = [] for log in logs: - # crawl to the top log + # crawl to the bottom log + while self.block_at(*padd(log, BLOCK_BELOW)) in blocks.LOG_IDS: + log = padd(log, BLOCK_BELOW) + + # crawl to the top log to count log_count = 1 while self.block_at(*padd(log, BLOCK_ABOVE)) in blocks.LOG_IDS: log = padd(log, BLOCK_ABOVE) @@ -495,15 +507,16 @@ class MCWorld: # make sure it's a good tree if self.block_at(*padd(log, BLOCK_ABOVE)) in blocks.LEAF_IDS and log_count > 2: - break - else: # for - return None + # crawl back to the bottom log + while self.block_at(*padd(log, BLOCK_BELOW)) in blocks.LOG_IDS: + log = padd(log, BLOCK_BELOW) + trees.append(log) - # crawl to the bottom log - while self.block_at(*padd(log, BLOCK_BELOW)) in blocks.LOG_IDS: - log = padd(log, BLOCK_BELOW) + print('before', trees) + trees.sort(key=lambda x: phyp(center, x)) + print('after', trees) - return log + return trees def find_tree_openings(self, tree): # returns coords in a cardinal direction where we can stand by tree @@ -553,8 +566,12 @@ class LumberjackStates: w = MCWorld(self.player_info.chunks) p = pint(self.player_info.pos) - self.tree = w.find_tree(p, 100) - print('Found tree at:', self.tree) + trees = w.find_trees(p, 100) + print('Found trees:', trees) + + while trees[0] in self.bad_trees: + trees.pop(0) + self.tree = trees[0] openings = w.find_tree_openings(self.tree) @@ -563,8 +580,10 @@ class LumberjackStates: self.opening = o if path: break else: # for - print('Unable to get to tree') + print('Unable to get to tree', self.tree) + self.bad_trees.append(self.tree) self.state = self.finished + return s['path'] = path self.state = self.going_to_tree @@ -572,11 +591,11 @@ class LumberjackStates: def going_to_tree(self): d = self.player_info.pos - LPoint3f(*self.opening) if d.length() < 1: - s['look_at'] = LPoint3f(*self.tree) + s['look_at'] = self.tree self.state = self.clear_leaves def clear_leaves(self): - if not s['break_finished_packet']: + if not s['break_timeout']: p = pint(self.player_info.pos) diff = psub(self.tree, p) @@ -592,16 +611,16 @@ class LumberjackStates: return def clear_trunk_base(self): - if not s['break_finished_packet']: + if not s['break_timeout']: base = self.tree above = padd(self.tree, BLOCK_ABOVE) if self.blog(base): - s['break'] = (base, 2) - return + s['break'] = (base, 3) + print('breaking base') elif self.blog(above): - s['break'] = (above, 2) - return + s['break'] = (above, 3) + print('breaking above') else: w = MCWorld(self.player_info.chunks) p = pint(self.player_info.pos) @@ -613,11 +632,11 @@ class LumberjackStates: def going_to_trunk_base(self): d = self.player_info.pos - LPoint3f(*self.opening) if d.length() < 1: - s['pitch'] = -90 + s['look_at'] = padd(self.tree, BLOCK_ABOVE2) self.state = self.clear_trunk def clear_trunk(self): - if not s['break_finished_packet']: + if not s['break_timeout']: check = self.tree count = 0 @@ -626,14 +645,22 @@ class LumberjackStates: count += 1 if self.blog(check): - s['break'] = (check, 2) + print('breaking log', check) + s['break'] = (check, 3) else: print('Finished clearing tree') - self.state = self.finished + self.wait_time = 0.5 + s['look_at'] = None + self.state = self.wait + + def wait(self): + # wait for the last log to fall + if self.wait_time > 0: + self.wait_time -= TICK + else: + self.state = self.finished def finished(self): - s['pitch'] = 0 # todo, calc with look_at - s['look_at'] = None return None @@ -643,6 +670,8 @@ class LumberjackStates: self.tree = None self.opening = None + self.bad_trees = [] + self.wait_time = 0 def run(self): self.state() @@ -659,6 +688,10 @@ class JobStates: l = self.lumberjack_states if l.state == l.idle: l.state = l.find_new_tree + elif l.state == l.finished: + # check time, etc + l.state = l.find_new_tree + l.run() def __init__(self, player_info): @@ -671,8 +704,11 @@ class JobStates: TICK = 0.05 -ANGLE_DIR = LVector3f(x=0, y=0, z=-1) -ANGLE_REF = LVector3f(x=0, y=1, z=0) +last_tick = time.time() + +PITCH_ANGLE_DIR = LVector3f(x=0, y=1, z=0) +YAW_ANGLE_DIR = LVector3f(x=0, y=0, z=-1) +YAW_ANGLE_REF = LVector3f(x=0, y=1, z=0) YAW_LOOK_AHEAD = 4 running = True @@ -684,7 +720,6 @@ last_mod_time = get_mod_time() s = dict() -pitch = 0 @@ -700,7 +735,7 @@ def tick(connection, player_info): p = player_info.pos - if len(s['path']): + if s['path'] and len(s['path']): target = LPoint3f(s['path'][0]) target.x += 0.5 target.z += 0.5 @@ -710,7 +745,7 @@ def tick(connection, player_info): # jump up block if d.y < -0.9 and not s['y_v']: - s['y_v'] = 10.0 + s['y_v'] = 8.5 s['y_a'] = -36.0 # jump gap @@ -729,7 +764,7 @@ def tick(connection, player_info): p.y += s['y_v'] * TICK s['y_v'] += s['y_a'] * TICK - if player_info.chunks.get_block_at(int(p.x), ceil(p.y-1), int(p.z)) not in blocks.NON_SOLID_IDS: + if player_info.chunks.get_block_at(floor(p.x), ceil(p.y-1), floor(p.z)) not in blocks.NON_SOLID_IDS: p.y = ceil(p.y) s['y_v'] = 0 s['y_a'] = 0 @@ -739,9 +774,9 @@ def tick(connection, player_info): if s['look_at']: look_at = LPoint3f(s['look_at']) - elif len(s['path']) > YAW_LOOK_AHEAD: + elif s['path'] and len(s['path']) > YAW_LOOK_AHEAD: look_at = LPoint3f(s['path'][YAW_LOOK_AHEAD]) - elif len(s['path']): + elif s['path'] and len(s['path']): look_at = LPoint3f(s['path'][-1]) else: look_at = None @@ -752,11 +787,19 @@ def tick(connection, player_info): look_at_d = p - look_at if look_at_d.length() > 0.6: - target_yaw = look_at_d.normalized().signedAngleDeg(other=ANGLE_DIR, ref=ANGLE_REF) + target_yaw = look_at_d.normalized().signedAngleDeg(other=YAW_ANGLE_DIR, ref=YAW_ANGLE_REF) target_yaw_d = target_yaw - s['yaw'] target_yaw_d = (target_yaw_d + 180) % 360 - 180 s['yaw'] += cap(target_yaw_d, 30) + target_pitch = look_at_d.normalized().angleDeg(PITCH_ANGLE_DIR) + target_pitch = (target_pitch - 90) * -1 + target_pitch_d = target_pitch - s['pitch'] + s['pitch'] += cap(target_pitch_d, 10) + else: + target_pitch_d = 0 - s['pitch'] + s['pitch'] += cap(target_pitch_d, 10) + packet = serverbound.play.PositionAndLookPacket(x=p.x, feet_y=p.y, z=p.z, pitch=s['pitch'], yaw=s['yaw'], on_ground=True) @@ -771,10 +814,17 @@ def tick(connection, player_info): packet.hand = packet.HAND_MAIN connection.write_packet(packet) + #print(s['break_time']) s['break_time'] -= TICK elif s['break_finished_packet']: + print('break finished') connection.write_packet(s['break_finished_packet']) s['break_finished_packet'] = None + elif s['break_timeout'] > 0: + s['break_timeout'] -= TICK + + if s['break_timeout'] < 0: + s['break_timeout'] = 0 @@ -791,6 +841,7 @@ def init(connection, player_info): s['break'] = None s['break_time'] = 0 + s['break_timeout'] = 0 s['break_finished_packet'] = None s['jobstate'] = JobStates(player_info) @@ -828,6 +879,7 @@ def main(connection, player_info): solution = list(solution) s['path'] = solution print(len(solution)) + print(solution) print(round(time.time() - start, 3), 'seconds') else: packet = serverbound.play.ChatPacket() @@ -964,7 +1016,13 @@ def main(connection, player_info): while running: tick(connection, player_info) - time.sleep(TICK) + + global last_tick + sleep_time = TICK + last_tick - time.time() + if sleep_time < 0: sleep_time = 0 + + time.sleep(sleep_time) + last_tick = time.time() if get_mod_time() != last_mod_time: break