|
|
|
@ -13,6 +13,7 @@ from minecraft import authentication |
|
|
|
|
from minecraft.exceptions import YggdrasilError |
|
|
|
|
from minecraft.networking.connection import Connection |
|
|
|
|
from minecraft.networking.packets import clientbound, serverbound |
|
|
|
|
from minecraft.networking.types import BlockFace |
|
|
|
|
from minecraft.compat import input |
|
|
|
|
from minecraft.managers import chunks, ChunksManager |
|
|
|
|
|
|
|
|
@ -37,6 +38,7 @@ BLOCK_ABOVE2 = (0, +2, 0) |
|
|
|
|
BLOCK_ABOVE3 = (0, +3, 0) |
|
|
|
|
BLOCK_ABOVE4 = (0, +4, 0) |
|
|
|
|
BLOCK_BELOW = (0, -1, 0) |
|
|
|
|
BLOCK_BELOW2 = (0, -2, 0) |
|
|
|
|
|
|
|
|
|
TRAVERSE_NORTH = (0, 0, -1) |
|
|
|
|
TRAVERSE_SOUTH = (0, 0, +1) |
|
|
|
@ -152,6 +154,12 @@ def pmul(p, s): |
|
|
|
|
def phyp(p1, p2): |
|
|
|
|
return hypot(p1[0] - p2[0], p1[1] - p2[1], p1[2] - p2[2]) |
|
|
|
|
|
|
|
|
|
def phyp_bias(p1, p2, origin): |
|
|
|
|
origin_distance = phyp(origin, p2) |
|
|
|
|
height_diff = p2[1] - p1[1] |
|
|
|
|
height_diff = height_diff*8 if height_diff < 0 else height_diff*0.5 |
|
|
|
|
return hypot(p1[0] - p2[0], height_diff, p1[2] - p2[2]) + origin_distance*1.5 |
|
|
|
|
|
|
|
|
|
def pint(p): |
|
|
|
|
return (floor(p[0]), floor(p[1]), floor(p[2])) |
|
|
|
|
|
|
|
|
@ -380,11 +388,39 @@ def break_block(connection, coords, time): |
|
|
|
|
s['break_time'] = time |
|
|
|
|
s['break_timeout'] = 0.25 |
|
|
|
|
|
|
|
|
|
def place_block(connection, pos, face): |
|
|
|
|
packet = serverbound.play.PlayerBlockPlacementPacket() |
|
|
|
|
packet.hand = 0 |
|
|
|
|
packet.location = pos |
|
|
|
|
packet.face = face |
|
|
|
|
packet.x = 0.5 |
|
|
|
|
packet.y = 0.5 |
|
|
|
|
packet.z = 0.5 |
|
|
|
|
packet.inside_block = False |
|
|
|
|
connection.write_packet(packet) |
|
|
|
|
|
|
|
|
|
def say(connection, message): |
|
|
|
|
packet = serverbound.play.ChatPacket() |
|
|
|
|
packet.message = message |
|
|
|
|
connection.write_packet(packet) |
|
|
|
|
|
|
|
|
|
def pick(connection, slot): |
|
|
|
|
packet = custom_packets.PickItemPacket() |
|
|
|
|
packet.slot_to_use = slot |
|
|
|
|
connection.write_packet(packet) |
|
|
|
|
|
|
|
|
|
def hold(connection, slot): |
|
|
|
|
packet = custom_packets.HeldItemChangePacket() |
|
|
|
|
packet.slot = slot |
|
|
|
|
connection.write_packet(packet) |
|
|
|
|
|
|
|
|
|
def choose_slot(connection, slot): |
|
|
|
|
if slot >= 36: |
|
|
|
|
slot -= 36 |
|
|
|
|
hold(connection, slot) |
|
|
|
|
else: |
|
|
|
|
pick(connection, slot) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BLOCK_ABOVE = (0, +1, 0) |
|
|
|
|
BLOCK_BELOW = (0, -1, 0) |
|
|
|
@ -459,32 +495,90 @@ class MCWorld: |
|
|
|
|
maze_solver = MazeSolver(self.chunks) |
|
|
|
|
result = [] |
|
|
|
|
|
|
|
|
|
# TODO: make sure only non-solid and leaves between |
|
|
|
|
# make sure traversable too |
|
|
|
|
|
|
|
|
|
for distance in range(5): |
|
|
|
|
for direction in CHECK_DIRECTIONS: |
|
|
|
|
offset = (0, 0, 0) |
|
|
|
|
for _ in range(distance): |
|
|
|
|
offset = padd(offset, direction) |
|
|
|
|
offset = pmul(direction, distance+1) |
|
|
|
|
if maze_solver.check_traverse(tree, offset): |
|
|
|
|
result.append(padd(tree, offset)) |
|
|
|
|
return result |
|
|
|
|
|
|
|
|
|
def path_to_opening(self, start, opening): |
|
|
|
|
def path_to_place(self, start, place): |
|
|
|
|
maze_solver = MazeSolver(self.chunks) |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
s = maze_solver.astar(start, opening) |
|
|
|
|
s = maze_solver.astar(start, place) |
|
|
|
|
return list(s) if s else None |
|
|
|
|
except AStarTimeout: |
|
|
|
|
return None |
|
|
|
|
|
|
|
|
|
def path_to_base(self, start, base): |
|
|
|
|
maze_solver = MazeSolver(self.chunks) |
|
|
|
|
def find_bed_areas(self, center, distance): |
|
|
|
|
air = [] |
|
|
|
|
for i in range(5): |
|
|
|
|
check = padd(center, alternate(i, 1)) |
|
|
|
|
air.extend(self.find_blocks(check, distance, [0], 200)) |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
s = maze_solver.astar(start, base) |
|
|
|
|
return list(s) if s else None |
|
|
|
|
except AStarTimeout: |
|
|
|
|
return None |
|
|
|
|
areas = [] |
|
|
|
|
for a in air: |
|
|
|
|
# check for ground around the area |
|
|
|
|
if len(self.find_blocks(padd(a, BLOCK_BELOW), 2, blocks.NON_SOLID_IDS, 9)): |
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
# check for air around the area |
|
|
|
|
if len(self.find_blocks(a, 2, [0], 9)) < 9: |
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
# check for air above the area |
|
|
|
|
if len(self.find_blocks(padd(a, BLOCK_ABOVE), 2, [0], 9)) < 9: |
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
areas.append(a) |
|
|
|
|
|
|
|
|
|
areas.sort(key=lambda x: phyp(center, x)) |
|
|
|
|
return areas |
|
|
|
|
|
|
|
|
|
def sand_adjacent_safe(self, sand): |
|
|
|
|
for direction in CHECK_DIRECTIONS: |
|
|
|
|
if self.block_at(*padd(sand, direction)) in blocks.AVOID_IDS: |
|
|
|
|
return False |
|
|
|
|
return True |
|
|
|
|
|
|
|
|
|
def find_sand(self, center, distance, origin): |
|
|
|
|
sand = [] |
|
|
|
|
for i in range(10): |
|
|
|
|
check = padd(center, alternate(i, 1)) |
|
|
|
|
sand.extend(self.find_blocks(check, distance, [66], 20)) |
|
|
|
|
|
|
|
|
|
safe_sand = [] |
|
|
|
|
for s in sand: |
|
|
|
|
# make sure it has solid below |
|
|
|
|
if self.block_at(*padd(s, BLOCK_BELOW)) in blocks.NON_SOLID_IDS: |
|
|
|
|
continue |
|
|
|
|
# make sure it has solid two below - prevent hanging sand |
|
|
|
|
if self.block_at(*padd(s, BLOCK_BELOW2)) in blocks.NON_SOLID_IDS: |
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
# and walkable air above |
|
|
|
|
if self.block_at(*padd(s, BLOCK_ABOVE)) not in blocks.NON_SOLID_IDS: |
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
if not self.sand_adjacent_safe(s): |
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
safe_sand.append(s) |
|
|
|
|
|
|
|
|
|
safe_sand.sort(key=lambda x: phyp_bias(center, x, origin)) |
|
|
|
|
return safe_sand |
|
|
|
|
|
|
|
|
|
def find_bed_openings(self, area): |
|
|
|
|
# returns coords in a cardinal direction where we can stand by bed |
|
|
|
|
result = [] |
|
|
|
|
|
|
|
|
|
for direction in CHECK_DIRECTIONS: |
|
|
|
|
result.append(padd(area, direction)) |
|
|
|
|
return result |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class LumberjackStates: |
|
|
|
@ -512,24 +606,31 @@ class LumberjackStates: |
|
|
|
|
trees.pop(0) |
|
|
|
|
self.tree = trees[0] |
|
|
|
|
|
|
|
|
|
openings = w.find_tree_openings(self.tree) |
|
|
|
|
self.openings = w.find_tree_openings(self.tree) |
|
|
|
|
self.state = self.choose_opening |
|
|
|
|
|
|
|
|
|
for o in openings: |
|
|
|
|
path = w.path_to_opening(p, o) |
|
|
|
|
self.opening = o |
|
|
|
|
if path: break |
|
|
|
|
else: # for |
|
|
|
|
def choose_opening(self): |
|
|
|
|
w = MCWorld(self.player_info.chunks) |
|
|
|
|
p = pint(self.player_info.pos) |
|
|
|
|
|
|
|
|
|
print('openings:', self.openings) |
|
|
|
|
|
|
|
|
|
if not len(self.openings): |
|
|
|
|
print('Unable to get to tree', self.tree) |
|
|
|
|
self.bad_trees.append(self.tree) |
|
|
|
|
self.state = self.done |
|
|
|
|
self.state = self.cleanup |
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
s['path'] = path |
|
|
|
|
self.state = self.going_to_tree |
|
|
|
|
path = w.path_to_place(p, self.openings[0]) |
|
|
|
|
|
|
|
|
|
if path: |
|
|
|
|
s['path'] = path |
|
|
|
|
self.state = self.going_to_tree |
|
|
|
|
else: |
|
|
|
|
self.openings.pop(0) |
|
|
|
|
|
|
|
|
|
def going_to_tree(self): |
|
|
|
|
d = self.player_info.pos - LPoint3f(*self.opening) |
|
|
|
|
if d.length() < 1: |
|
|
|
|
if pint(self.player_info.pos) == self.openings[0]: |
|
|
|
|
s['look_at'] = self.tree |
|
|
|
|
self.state = self.clear_leaves |
|
|
|
|
|
|
|
|
@ -542,13 +643,15 @@ class LumberjackStates: |
|
|
|
|
for z in diffrange(diff[2]): |
|
|
|
|
for y in range(2): |
|
|
|
|
check = padd(p, (x, y, z)) |
|
|
|
|
if self.blog(check): |
|
|
|
|
self.state = self.clear_trunk_base |
|
|
|
|
return |
|
|
|
|
if check == self.tree: |
|
|
|
|
break |
|
|
|
|
if not self.bair(check): |
|
|
|
|
print('Breaking leaf') |
|
|
|
|
s['break'] = (check, 0.5) |
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
self.state = self.clear_trunk_base |
|
|
|
|
|
|
|
|
|
def clear_trunk_base(self): |
|
|
|
|
if not s['break_timeout']: |
|
|
|
|
base = self.tree |
|
|
|
@ -563,14 +666,17 @@ class LumberjackStates: |
|
|
|
|
else: |
|
|
|
|
w = MCWorld(self.player_info.chunks) |
|
|
|
|
p = pint(self.player_info.pos) |
|
|
|
|
path = w.path_to_base(p, self.tree) |
|
|
|
|
path = w.path_to_place(p, self.tree) |
|
|
|
|
|
|
|
|
|
s['path'] = path |
|
|
|
|
self.state = self.going_to_trunk_base |
|
|
|
|
if path: |
|
|
|
|
s['path'] = path |
|
|
|
|
self.state = self.going_to_trunk_base |
|
|
|
|
else: |
|
|
|
|
self.openings.pop(0) |
|
|
|
|
self.state = self.choose_opening |
|
|
|
|
|
|
|
|
|
def going_to_trunk_base(self): |
|
|
|
|
d = self.player_info.pos - LPoint3f(*self.opening) |
|
|
|
|
if d.length() < 1: |
|
|
|
|
if pint(self.player_info.pos) == self.tree: |
|
|
|
|
s['look_at'] = padd(self.tree, BLOCK_ABOVE2) |
|
|
|
|
self.state = self.clear_trunk |
|
|
|
|
|
|
|
|
@ -589,7 +695,6 @@ class LumberjackStates: |
|
|
|
|
else: |
|
|
|
|
print('Finished clearing tree') |
|
|
|
|
self.wait_time = 0.5 |
|
|
|
|
s['look_at'] = None |
|
|
|
|
self.state = self.wait |
|
|
|
|
|
|
|
|
|
def wait(self): |
|
|
|
@ -597,9 +702,14 @@ class LumberjackStates: |
|
|
|
|
if self.wait_time > 0: |
|
|
|
|
self.wait_time -= TICK |
|
|
|
|
else: |
|
|
|
|
self.state = self.done |
|
|
|
|
self.state = self.cleanup |
|
|
|
|
|
|
|
|
|
def cleanup(self): |
|
|
|
|
s['look_at'] = None |
|
|
|
|
self.state = self.done |
|
|
|
|
|
|
|
|
|
def done(self): |
|
|
|
|
# never gets ran, placeholder |
|
|
|
|
return None |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -608,7 +718,7 @@ class LumberjackStates: |
|
|
|
|
self.state = self.idle |
|
|
|
|
|
|
|
|
|
self.tree = None |
|
|
|
|
self.opening = None |
|
|
|
|
self.openings = [] |
|
|
|
|
self.bad_trees = [] |
|
|
|
|
self.wait_time = 0 |
|
|
|
|
|
|
|
|
@ -616,32 +726,283 @@ class LumberjackStates: |
|
|
|
|
self.state() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class JobStates: |
|
|
|
|
class GatherSandStates: |
|
|
|
|
def bair(self, p): |
|
|
|
|
return self.player_info.chunks.get_block_at(*p) in blocks.NON_SOLID_IDS |
|
|
|
|
|
|
|
|
|
def bsand(self, p): |
|
|
|
|
return self.player_info.chunks.get_block_at(*p) == 66 |
|
|
|
|
|
|
|
|
|
def idle(self): |
|
|
|
|
return None |
|
|
|
|
|
|
|
|
|
def night_shelter(self): |
|
|
|
|
def init(self): |
|
|
|
|
self.state = self.find_new_sand |
|
|
|
|
|
|
|
|
|
def find_new_sand(self): |
|
|
|
|
print('Finding new sand...') |
|
|
|
|
w = MCWorld(self.player_info.chunks) |
|
|
|
|
p = pint(self.player_info.pos) |
|
|
|
|
|
|
|
|
|
sand = w.find_sand(p, 150, self.origin) |
|
|
|
|
print('Found sand:', sand) |
|
|
|
|
|
|
|
|
|
while sand[0] in self.bad_sand: |
|
|
|
|
sand.pop(0) |
|
|
|
|
self.sand = sand[0] |
|
|
|
|
|
|
|
|
|
self.state = self.nav_to_sand |
|
|
|
|
|
|
|
|
|
def nav_to_sand(self): |
|
|
|
|
w = MCWorld(self.player_info.chunks) |
|
|
|
|
p = pint(self.player_info.pos) |
|
|
|
|
|
|
|
|
|
w.chunks.set_block_at(*self.sand, 0) |
|
|
|
|
path = w.path_to_place(p, self.sand) |
|
|
|
|
w.chunks.set_block_at(*self.sand, 66) |
|
|
|
|
|
|
|
|
|
if path: |
|
|
|
|
s['path'] = path[:-1] |
|
|
|
|
self.state = self.going_to_sand |
|
|
|
|
else: |
|
|
|
|
self.bad_sand.append(self.sand) |
|
|
|
|
self.state = self.find_new_sand |
|
|
|
|
|
|
|
|
|
def going_to_sand(self): |
|
|
|
|
if not len(s['path']): |
|
|
|
|
s['look_at'] = self.sand |
|
|
|
|
self.state = self.dig_sand |
|
|
|
|
|
|
|
|
|
def dig_sand(self): |
|
|
|
|
if not s['break_timeout']: |
|
|
|
|
if self.bsand(self.sand): |
|
|
|
|
s['break'] = (self.sand, 0.75) |
|
|
|
|
print('digging sand') |
|
|
|
|
else: |
|
|
|
|
self.state = self.get_sand |
|
|
|
|
|
|
|
|
|
def get_sand(self): |
|
|
|
|
w = MCWorld(self.player_info.chunks) |
|
|
|
|
p = pint(self.player_info.pos) |
|
|
|
|
path = w.path_to_place(p, self.sand) |
|
|
|
|
|
|
|
|
|
if path: |
|
|
|
|
s['path'] = path |
|
|
|
|
self.state = self.going_to_item |
|
|
|
|
else: |
|
|
|
|
self.bad_sand.append(self.sand) |
|
|
|
|
self.state = self.find_new_sand |
|
|
|
|
|
|
|
|
|
def going_to_item(self): |
|
|
|
|
if pint(self.player_info.pos) == self.sand: |
|
|
|
|
s['look_at'] = self.sand |
|
|
|
|
self.state = self.cleanup |
|
|
|
|
|
|
|
|
|
def cleanup(self): |
|
|
|
|
s['look_at'] = None |
|
|
|
|
self.state = self.done |
|
|
|
|
|
|
|
|
|
def done(self): |
|
|
|
|
# never gets ran, placeholder |
|
|
|
|
return None |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, player_info): |
|
|
|
|
self.player_info = player_info |
|
|
|
|
self.state = self.idle |
|
|
|
|
|
|
|
|
|
self.origin = pint(self.player_info.pos) |
|
|
|
|
self.sand = None |
|
|
|
|
self.bad_sand = [] |
|
|
|
|
self.wait_time = 0 |
|
|
|
|
|
|
|
|
|
def run(self): |
|
|
|
|
self.state() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SleepWithBedStates: |
|
|
|
|
def idle(self): |
|
|
|
|
return None |
|
|
|
|
|
|
|
|
|
def init(self): |
|
|
|
|
if s['time'] >= 12000: |
|
|
|
|
self.state = self.find_bed_spot |
|
|
|
|
else: |
|
|
|
|
print('Aborting sleep, not night') |
|
|
|
|
self.state = self.cleanup |
|
|
|
|
|
|
|
|
|
def find_bed_spot(self): |
|
|
|
|
print('Finding a bed spot...') |
|
|
|
|
w = MCWorld(self.player_info.chunks) |
|
|
|
|
p = pint(self.player_info.pos) |
|
|
|
|
|
|
|
|
|
areas = w.find_bed_areas(p, 100) |
|
|
|
|
print('Found areas:', areas) |
|
|
|
|
|
|
|
|
|
if len(areas): |
|
|
|
|
while areas[0] in self.bad_areas: |
|
|
|
|
areas.pop(0) |
|
|
|
|
self.area = areas[0] |
|
|
|
|
elif self.last_area: |
|
|
|
|
self.area = self.last_area |
|
|
|
|
else: |
|
|
|
|
print('Unable to find area, and no last area') |
|
|
|
|
self.state = self.cleanup |
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
openings = w.find_bed_openings(self.area) |
|
|
|
|
|
|
|
|
|
for o in openings: |
|
|
|
|
path = w.path_to_place(p, o) |
|
|
|
|
self.opening = o |
|
|
|
|
if path: break |
|
|
|
|
else: # for |
|
|
|
|
print('Unable to get to bed area', self.area) |
|
|
|
|
self.bad_areas.append(self.area) |
|
|
|
|
self.state = self.cleanup |
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
s['path'] = path |
|
|
|
|
self.state = self.going_to_area |
|
|
|
|
self.last_area = self.area |
|
|
|
|
|
|
|
|
|
def going_to_area(self): |
|
|
|
|
if pint(self.player_info.pos) == self.opening: |
|
|
|
|
s['look_at'] = self.area |
|
|
|
|
self.state = self.select_bed |
|
|
|
|
|
|
|
|
|
def select_bed(self): |
|
|
|
|
for slot, item in self.player_info.inv.items(): |
|
|
|
|
if item.item_id in items.BED_IDS: |
|
|
|
|
print('Found bed in slot', slot) |
|
|
|
|
s['look_at'] = padd(self.area, BLOCK_BELOW) |
|
|
|
|
choose_slot(self.connection, slot) |
|
|
|
|
self.state = self.place_bed |
|
|
|
|
break |
|
|
|
|
else: # for |
|
|
|
|
say(self.connection, 'I need a bed') |
|
|
|
|
self.state = self.cleanup |
|
|
|
|
|
|
|
|
|
def place_bed(self): |
|
|
|
|
place_block(self.connection, self.area, BlockFace.TOP) |
|
|
|
|
self.state = self.use_bed |
|
|
|
|
|
|
|
|
|
def use_bed(self): |
|
|
|
|
if s['time'] >= 12542: |
|
|
|
|
print('Sleeping') |
|
|
|
|
place_block(self.connection, self.area, BlockFace.TOP) |
|
|
|
|
say(self.connection, 'zzz') |
|
|
|
|
self.state = self.sleep_bed |
|
|
|
|
|
|
|
|
|
def sleep_bed(self): |
|
|
|
|
if s['time'] < 100: |
|
|
|
|
print('Woke up') |
|
|
|
|
self.state = self.break_bed |
|
|
|
|
|
|
|
|
|
def break_bed(self): |
|
|
|
|
s['break'] = (self.area, 0.4) |
|
|
|
|
self.state = self.collect_bed |
|
|
|
|
|
|
|
|
|
def collect_bed(self): |
|
|
|
|
if not s['break_timeout']: |
|
|
|
|
s['path'] = [padd(self.area, spiral(n)) for n in range(9)] |
|
|
|
|
self.wait_time = 4 |
|
|
|
|
self.state = self.wait |
|
|
|
|
|
|
|
|
|
def wait(self): |
|
|
|
|
# wait to pick up bed |
|
|
|
|
if self.wait_time > 0: |
|
|
|
|
self.wait_time -= TICK |
|
|
|
|
else: |
|
|
|
|
self.state = self.cleanup |
|
|
|
|
|
|
|
|
|
def cleanup(self): |
|
|
|
|
s['look_at'] = None |
|
|
|
|
self.state = self.done |
|
|
|
|
|
|
|
|
|
def done(self): |
|
|
|
|
# never gets ran, placeholder |
|
|
|
|
return None |
|
|
|
|
|
|
|
|
|
def __init__(self, player_info, connection): |
|
|
|
|
self.player_info = player_info |
|
|
|
|
self.connection = connection |
|
|
|
|
self.state = self.idle |
|
|
|
|
|
|
|
|
|
self.area = None |
|
|
|
|
self.opening = None |
|
|
|
|
self.bad_areas = [] |
|
|
|
|
self.last_area = None |
|
|
|
|
self.wait_time = 0 |
|
|
|
|
|
|
|
|
|
def run(self): |
|
|
|
|
self.state() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class JobStates: |
|
|
|
|
def idle(self): |
|
|
|
|
return None |
|
|
|
|
|
|
|
|
|
def sleep_with_bed(self): |
|
|
|
|
s = self.sleep_with_bed_states |
|
|
|
|
if s.state == s.idle: |
|
|
|
|
s.state = s.init |
|
|
|
|
elif s.state == s.done: |
|
|
|
|
s.state = s.init |
|
|
|
|
# check time, etc |
|
|
|
|
|
|
|
|
|
if self.prev_state: |
|
|
|
|
print('Reverting to prev state') |
|
|
|
|
self.state = self.prev_state |
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
s.run() |
|
|
|
|
|
|
|
|
|
def gather_sand(self): |
|
|
|
|
s = self.gather_sand_states |
|
|
|
|
if s.state == s.idle: |
|
|
|
|
s.state = s.init |
|
|
|
|
elif s.state == s.done: |
|
|
|
|
s.state = s.init |
|
|
|
|
# check time, etc |
|
|
|
|
|
|
|
|
|
if self.survive: |
|
|
|
|
self.prev_state = self.gather_sand |
|
|
|
|
self.state = self.sleep_with_bed |
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
s.run() |
|
|
|
|
|
|
|
|
|
def lumberjack(self): |
|
|
|
|
l = self.lumberjack_states |
|
|
|
|
if l.state == l.idle: |
|
|
|
|
l.state = l.init |
|
|
|
|
elif l.state == l.done: |
|
|
|
|
s = self.lumberjack_states |
|
|
|
|
if s.state == s.idle: |
|
|
|
|
s.state = s.init |
|
|
|
|
elif s.state == s.done: |
|
|
|
|
s.state = s.init |
|
|
|
|
# check time, etc |
|
|
|
|
l.state = l.init |
|
|
|
|
|
|
|
|
|
l.run() |
|
|
|
|
if self.survive: |
|
|
|
|
self.prev_state = self.lumberjack |
|
|
|
|
self.state = self.sleep_with_bed |
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
s.run() |
|
|
|
|
|
|
|
|
|
def stop(self): |
|
|
|
|
self.lumberjack_states = LumberjackStates(self.player_info) |
|
|
|
|
self.gather_sand_states = GatherSandStates(self.player_info) |
|
|
|
|
self.sleep_with_bed_states = SleepWithBedStates(self.player_info, self.connection) |
|
|
|
|
self.state = self.idle |
|
|
|
|
|
|
|
|
|
def __init__(self, connection, player_info): |
|
|
|
|
# TODO: watch dog if it gets stuck |
|
|
|
|
self.connection = connection |
|
|
|
|
self.player_info = player_info |
|
|
|
|
self.state = self.idle |
|
|
|
|
self.prev_state = None |
|
|
|
|
self.lumberjack_states = LumberjackStates(self.player_info) |
|
|
|
|
self.gather_sand_states = GatherSandStates(self.player_info) |
|
|
|
|
self.sleep_with_bed_states = SleepWithBedStates(self.player_info, self.connection) |
|
|
|
|
self.survive = False |
|
|
|
|
|
|
|
|
|
def run(self): |
|
|
|
@ -744,15 +1105,18 @@ 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=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) |
|
|
|
|
|
|
|
|
|
# remove vertical component for yaw calculation |
|
|
|
|
look_at_d.y = 0 |
|
|
|
|
|
|
|
|
|
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) |
|
|
|
|
else: |
|
|
|
|
target_pitch_d = 0 - s['pitch'] |
|
|
|
|
s['pitch'] += cap(target_pitch_d, 10) |
|
|
|
@ -788,6 +1152,8 @@ def tick(connection, player_info): |
|
|
|
|
def init(connection, player_info): |
|
|
|
|
p = player_info.pos |
|
|
|
|
|
|
|
|
|
s['time'] = 0 |
|
|
|
|
|
|
|
|
|
s['path'] = [] |
|
|
|
|
s['look_at'] = None |
|
|
|
|
s['y_v'] = 0 |
|
|
|
@ -803,6 +1169,7 @@ def init(connection, player_info): |
|
|
|
|
s['jobstate'] = JobStates(connection, player_info) |
|
|
|
|
s['jobstate'].run() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main(connection, player_info): |
|
|
|
|
def handle_join_game(join_game_packet): |
|
|
|
|
print('Connected.') |
|
|
|
@ -850,11 +1217,11 @@ def main(connection, player_info): |
|
|
|
|
connection.register_packet_listener( |
|
|
|
|
x, clientbound.play.BlockChangePacket) |
|
|
|
|
|
|
|
|
|
#def y(p): |
|
|
|
|
# print(p) |
|
|
|
|
def handle_time_update(p): |
|
|
|
|
s['time'] = p.time_of_day % 24000 |
|
|
|
|
|
|
|
|
|
#connection.register_packet_listener( |
|
|
|
|
# y, AcknowledgePlayerDiggingPacket) |
|
|
|
|
connection.register_packet_listener( |
|
|
|
|
handle_time_update, custom_packets.TimeUpdatePacket) |
|
|
|
|
|
|
|
|
|
def handle_set_slot(p): |
|
|
|
|
print(p) |
|
|
|
@ -872,6 +1239,9 @@ def main(connection, player_info): |
|
|
|
|
if '!reload' in chat_packet.json_data: |
|
|
|
|
global running |
|
|
|
|
running = False |
|
|
|
|
elif '!misc' in chat_packet.json_data: |
|
|
|
|
for i in range(9): |
|
|
|
|
print(i, spiral(i)) |
|
|
|
|
elif '!afk' in chat_packet.json_data: |
|
|
|
|
say(connection, '/afk') |
|
|
|
|
elif '!respawn' in chat_packet.json_data: |
|
|
|
@ -919,11 +1289,29 @@ def main(connection, player_info): |
|
|
|
|
for i in player_info.inv.values(): |
|
|
|
|
if i.present: |
|
|
|
|
print(items.ITEM_NAMES[i.item_id], 'x', i.item_count) |
|
|
|
|
elif '!spot' in chat_packet.json_data: |
|
|
|
|
mc_world = MCWorld(player_info.chunks) |
|
|
|
|
start = time.time() |
|
|
|
|
coords = mc_world.find_bed_areas(pint(player_info.pos), 100) |
|
|
|
|
print(coords) |
|
|
|
|
print(len(coords)) |
|
|
|
|
print(round(time.time() - start, 3), 'seconds') |
|
|
|
|
elif '!echo' in chat_packet.json_data: |
|
|
|
|
parts = chat_packet.json_data.split('\'') |
|
|
|
|
say(connection, parts[1]) |
|
|
|
|
elif '!sleep' in chat_packet.json_data: |
|
|
|
|
#for i in player_info.inv.values(): |
|
|
|
|
# if i.item_id in items.BED_IDS: |
|
|
|
|
# break |
|
|
|
|
#else: # for |
|
|
|
|
# say(connection, 'I need a bed') |
|
|
|
|
# return |
|
|
|
|
|
|
|
|
|
s['jobstate'].state = s['jobstate'].sleep_with_bed |
|
|
|
|
s['jobstate'].sleep_with_bed_states.state = s['jobstate'].sleep_with_bed_states.find_bed_spot |
|
|
|
|
elif 'get wood and survive' in chat_packet.json_data: |
|
|
|
|
for i in player_info.inv.values(): |
|
|
|
|
print(i.item_id) |
|
|
|
|
if i.item_id in items.BED_IDS: |
|
|
|
|
break |
|
|
|
|
else: # for |
|
|
|
@ -932,8 +1320,21 @@ def main(connection, player_info): |
|
|
|
|
|
|
|
|
|
s['jobstate'].state = s['jobstate'].lumberjack |
|
|
|
|
s['jobstate'].survive = True |
|
|
|
|
elif 'get sand and survive' in chat_packet.json_data: |
|
|
|
|
for i in player_info.inv.values(): |
|
|
|
|
print(i.item_id) |
|
|
|
|
if i.item_id in items.BED_IDS: |
|
|
|
|
break |
|
|
|
|
else: # for |
|
|
|
|
say(connection, 'I need a bed') |
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
s['jobstate'].state = s['jobstate'].gather_sand |
|
|
|
|
s['jobstate'].survive = True |
|
|
|
|
elif 'get wood' in chat_packet.json_data: |
|
|
|
|
s['jobstate'].state = s['jobstate'].lumberjack |
|
|
|
|
elif 'get sand' in chat_packet.json_data: |
|
|
|
|
s['jobstate'].state = s['jobstate'].gather_sand |
|
|
|
|
elif 'stop job' in chat_packet.json_data: |
|
|
|
|
say(connection, 'ok') |
|
|
|
|
s['jobstate'].state = s['jobstate'].stop |
|
|
|
|