Gather sand and sleep at night
This commit is contained in:
parent
ebc9c5ef1a
commit
49412e0253
|
@ -43,12 +43,6 @@ AVOID = [
|
||||||
|
|
||||||
NON_SOLID = [
|
NON_SOLID = [
|
||||||
'minecraft:air',
|
'minecraft:air',
|
||||||
'minecraft:oak_sapling',
|
|
||||||
'minecraft:spruce_sapling',
|
|
||||||
'minecraft:birch_sapling',
|
|
||||||
'minecraft:jungle_sapling',
|
|
||||||
'minecraft:acacia_sapling',
|
|
||||||
'minecraft:dark_oak_sapling',
|
|
||||||
'minecraft:powered_rail',
|
'minecraft:powered_rail',
|
||||||
'minecraft:detector_rail',
|
'minecraft:detector_rail',
|
||||||
'minecraft:grass',
|
'minecraft:grass',
|
||||||
|
|
493
bot.py
493
bot.py
|
@ -13,6 +13,7 @@ from minecraft import authentication
|
||||||
from minecraft.exceptions import YggdrasilError
|
from minecraft.exceptions import YggdrasilError
|
||||||
from minecraft.networking.connection import Connection
|
from minecraft.networking.connection import Connection
|
||||||
from minecraft.networking.packets import clientbound, serverbound
|
from minecraft.networking.packets import clientbound, serverbound
|
||||||
|
from minecraft.networking.types import BlockFace
|
||||||
from minecraft.compat import input
|
from minecraft.compat import input
|
||||||
from minecraft.managers import chunks, ChunksManager
|
from minecraft.managers import chunks, ChunksManager
|
||||||
|
|
||||||
|
@ -37,6 +38,7 @@ BLOCK_ABOVE2 = (0, +2, 0)
|
||||||
BLOCK_ABOVE3 = (0, +3, 0)
|
BLOCK_ABOVE3 = (0, +3, 0)
|
||||||
BLOCK_ABOVE4 = (0, +4, 0)
|
BLOCK_ABOVE4 = (0, +4, 0)
|
||||||
BLOCK_BELOW = (0, -1, 0)
|
BLOCK_BELOW = (0, -1, 0)
|
||||||
|
BLOCK_BELOW2 = (0, -2, 0)
|
||||||
|
|
||||||
TRAVERSE_NORTH = (0, 0, -1)
|
TRAVERSE_NORTH = (0, 0, -1)
|
||||||
TRAVERSE_SOUTH = (0, 0, +1)
|
TRAVERSE_SOUTH = (0, 0, +1)
|
||||||
|
@ -152,6 +154,12 @@ def pmul(p, s):
|
||||||
def phyp(p1, p2):
|
def phyp(p1, p2):
|
||||||
return hypot(p1[0] - p2[0], p1[1] - p2[1], p1[2] - p2[2])
|
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):
|
def pint(p):
|
||||||
return (floor(p[0]), floor(p[1]), floor(p[2]))
|
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_time'] = time
|
||||||
s['break_timeout'] = 0.25
|
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):
|
def say(connection, message):
|
||||||
packet = serverbound.play.ChatPacket()
|
packet = serverbound.play.ChatPacket()
|
||||||
packet.message = message
|
packet.message = message
|
||||||
connection.write_packet(packet)
|
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_ABOVE = (0, +1, 0)
|
||||||
BLOCK_BELOW = (0, -1, 0)
|
BLOCK_BELOW = (0, -1, 0)
|
||||||
|
@ -459,32 +495,90 @@ class MCWorld:
|
||||||
maze_solver = MazeSolver(self.chunks)
|
maze_solver = MazeSolver(self.chunks)
|
||||||
result = []
|
result = []
|
||||||
|
|
||||||
|
# TODO: make sure only non-solid and leaves between
|
||||||
|
# make sure traversable too
|
||||||
|
|
||||||
for distance in range(5):
|
for distance in range(5):
|
||||||
for direction in CHECK_DIRECTIONS:
|
for direction in CHECK_DIRECTIONS:
|
||||||
offset = (0, 0, 0)
|
offset = pmul(direction, distance+1)
|
||||||
for _ in range(distance):
|
|
||||||
offset = padd(offset, direction)
|
|
||||||
if maze_solver.check_traverse(tree, offset):
|
if maze_solver.check_traverse(tree, offset):
|
||||||
result.append(padd(tree, offset))
|
result.append(padd(tree, offset))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def path_to_opening(self, start, opening):
|
def path_to_place(self, start, place):
|
||||||
maze_solver = MazeSolver(self.chunks)
|
maze_solver = MazeSolver(self.chunks)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
s = maze_solver.astar(start, opening)
|
s = maze_solver.astar(start, place)
|
||||||
return list(s) if s else None
|
return list(s) if s else None
|
||||||
except AStarTimeout:
|
except AStarTimeout:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def path_to_base(self, start, base):
|
def find_bed_areas(self, center, distance):
|
||||||
maze_solver = MazeSolver(self.chunks)
|
air = []
|
||||||
|
for i in range(5):
|
||||||
|
check = padd(center, alternate(i, 1))
|
||||||
|
air.extend(self.find_blocks(check, distance, [0], 200))
|
||||||
|
|
||||||
try:
|
areas = []
|
||||||
s = maze_solver.astar(start, base)
|
for a in air:
|
||||||
return list(s) if s else None
|
# check for ground around the area
|
||||||
except AStarTimeout:
|
if len(self.find_blocks(padd(a, BLOCK_BELOW), 2, blocks.NON_SOLID_IDS, 9)):
|
||||||
return None
|
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:
|
class LumberjackStates:
|
||||||
|
@ -512,24 +606,31 @@ class LumberjackStates:
|
||||||
trees.pop(0)
|
trees.pop(0)
|
||||||
self.tree = trees[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:
|
def choose_opening(self):
|
||||||
path = w.path_to_opening(p, o)
|
w = MCWorld(self.player_info.chunks)
|
||||||
self.opening = o
|
p = pint(self.player_info.pos)
|
||||||
if path: break
|
|
||||||
else: # for
|
print('openings:', self.openings)
|
||||||
|
|
||||||
|
if not len(self.openings):
|
||||||
print('Unable to get to tree', self.tree)
|
print('Unable to get to tree', self.tree)
|
||||||
self.bad_trees.append(self.tree)
|
self.bad_trees.append(self.tree)
|
||||||
self.state = self.done
|
self.state = self.cleanup
|
||||||
return
|
return
|
||||||
|
|
||||||
|
path = w.path_to_place(p, self.openings[0])
|
||||||
|
|
||||||
|
if path:
|
||||||
s['path'] = path
|
s['path'] = path
|
||||||
self.state = self.going_to_tree
|
self.state = self.going_to_tree
|
||||||
|
else:
|
||||||
|
self.openings.pop(0)
|
||||||
|
|
||||||
def going_to_tree(self):
|
def going_to_tree(self):
|
||||||
d = self.player_info.pos - LPoint3f(*self.opening)
|
if pint(self.player_info.pos) == self.openings[0]:
|
||||||
if d.length() < 1:
|
|
||||||
s['look_at'] = self.tree
|
s['look_at'] = self.tree
|
||||||
self.state = self.clear_leaves
|
self.state = self.clear_leaves
|
||||||
|
|
||||||
|
@ -542,13 +643,15 @@ class LumberjackStates:
|
||||||
for z in diffrange(diff[2]):
|
for z in diffrange(diff[2]):
|
||||||
for y in range(2):
|
for y in range(2):
|
||||||
check = padd(p, (x, y, z))
|
check = padd(p, (x, y, z))
|
||||||
if self.blog(check):
|
if check == self.tree:
|
||||||
self.state = self.clear_trunk_base
|
break
|
||||||
return
|
|
||||||
if not self.bair(check):
|
if not self.bair(check):
|
||||||
|
print('Breaking leaf')
|
||||||
s['break'] = (check, 0.5)
|
s['break'] = (check, 0.5)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
self.state = self.clear_trunk_base
|
||||||
|
|
||||||
def clear_trunk_base(self):
|
def clear_trunk_base(self):
|
||||||
if not s['break_timeout']:
|
if not s['break_timeout']:
|
||||||
base = self.tree
|
base = self.tree
|
||||||
|
@ -563,14 +666,17 @@ class LumberjackStates:
|
||||||
else:
|
else:
|
||||||
w = MCWorld(self.player_info.chunks)
|
w = MCWorld(self.player_info.chunks)
|
||||||
p = pint(self.player_info.pos)
|
p = pint(self.player_info.pos)
|
||||||
path = w.path_to_base(p, self.tree)
|
path = w.path_to_place(p, self.tree)
|
||||||
|
|
||||||
|
if path:
|
||||||
s['path'] = path
|
s['path'] = path
|
||||||
self.state = self.going_to_trunk_base
|
self.state = self.going_to_trunk_base
|
||||||
|
else:
|
||||||
|
self.openings.pop(0)
|
||||||
|
self.state = self.choose_opening
|
||||||
|
|
||||||
def going_to_trunk_base(self):
|
def going_to_trunk_base(self):
|
||||||
d = self.player_info.pos - LPoint3f(*self.opening)
|
if pint(self.player_info.pos) == self.tree:
|
||||||
if d.length() < 1:
|
|
||||||
s['look_at'] = padd(self.tree, BLOCK_ABOVE2)
|
s['look_at'] = padd(self.tree, BLOCK_ABOVE2)
|
||||||
self.state = self.clear_trunk
|
self.state = self.clear_trunk
|
||||||
|
|
||||||
|
@ -589,7 +695,6 @@ class LumberjackStates:
|
||||||
else:
|
else:
|
||||||
print('Finished clearing tree')
|
print('Finished clearing tree')
|
||||||
self.wait_time = 0.5
|
self.wait_time = 0.5
|
||||||
s['look_at'] = None
|
|
||||||
self.state = self.wait
|
self.state = self.wait
|
||||||
|
|
||||||
def wait(self):
|
def wait(self):
|
||||||
|
@ -597,9 +702,14 @@ class LumberjackStates:
|
||||||
if self.wait_time > 0:
|
if self.wait_time > 0:
|
||||||
self.wait_time -= TICK
|
self.wait_time -= TICK
|
||||||
else:
|
else:
|
||||||
|
self.state = self.cleanup
|
||||||
|
|
||||||
|
def cleanup(self):
|
||||||
|
s['look_at'] = None
|
||||||
self.state = self.done
|
self.state = self.done
|
||||||
|
|
||||||
def done(self):
|
def done(self):
|
||||||
|
# never gets ran, placeholder
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
@ -608,7 +718,7 @@ class LumberjackStates:
|
||||||
self.state = self.idle
|
self.state = self.idle
|
||||||
|
|
||||||
self.tree = None
|
self.tree = None
|
||||||
self.opening = None
|
self.openings = []
|
||||||
self.bad_trees = []
|
self.bad_trees = []
|
||||||
self.wait_time = 0
|
self.wait_time = 0
|
||||||
|
|
||||||
|
@ -616,32 +726,283 @@ class LumberjackStates:
|
||||||
self.state()
|
self.state()
|
||||||
|
|
||||||
|
|
||||||
|
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 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:
|
class JobStates:
|
||||||
def idle(self):
|
def idle(self):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def night_shelter(self):
|
def sleep_with_bed(self):
|
||||||
return None
|
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):
|
def lumberjack(self):
|
||||||
l = self.lumberjack_states
|
s = self.lumberjack_states
|
||||||
if l.state == l.idle:
|
if s.state == s.idle:
|
||||||
l.state = l.init
|
s.state = s.init
|
||||||
elif l.state == l.done:
|
elif s.state == s.done:
|
||||||
|
s.state = s.init
|
||||||
# check time, etc
|
# 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):
|
def stop(self):
|
||||||
self.lumberjack_states = LumberjackStates(self.player_info)
|
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
|
self.state = self.idle
|
||||||
|
|
||||||
def __init__(self, connection, player_info):
|
def __init__(self, connection, player_info):
|
||||||
|
# TODO: watch dog if it gets stuck
|
||||||
self.connection = connection
|
self.connection = connection
|
||||||
self.player_info = player_info
|
self.player_info = player_info
|
||||||
self.state = self.idle
|
self.state = self.idle
|
||||||
|
self.prev_state = None
|
||||||
self.lumberjack_states = LumberjackStates(self.player_info)
|
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
|
self.survive = False
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
@ -744,15 +1105,18 @@ def tick(connection, player_info):
|
||||||
look_at_d = p - look_at
|
look_at_d = p - look_at
|
||||||
|
|
||||||
if look_at_d.length() > 0.6:
|
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 = look_at_d.normalized().angleDeg(PITCH_ANGLE_DIR)
|
||||||
target_pitch = (target_pitch - 90) * -1
|
target_pitch = (target_pitch - 90) * -1
|
||||||
target_pitch_d = target_pitch - s['pitch']
|
target_pitch_d = target_pitch - s['pitch']
|
||||||
s['pitch'] += cap(target_pitch_d, 10)
|
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:
|
else:
|
||||||
target_pitch_d = 0 - s['pitch']
|
target_pitch_d = 0 - s['pitch']
|
||||||
s['pitch'] += cap(target_pitch_d, 10)
|
s['pitch'] += cap(target_pitch_d, 10)
|
||||||
|
@ -788,6 +1152,8 @@ def tick(connection, player_info):
|
||||||
def init(connection, player_info):
|
def init(connection, player_info):
|
||||||
p = player_info.pos
|
p = player_info.pos
|
||||||
|
|
||||||
|
s['time'] = 0
|
||||||
|
|
||||||
s['path'] = []
|
s['path'] = []
|
||||||
s['look_at'] = None
|
s['look_at'] = None
|
||||||
s['y_v'] = 0
|
s['y_v'] = 0
|
||||||
|
@ -803,6 +1169,7 @@ def init(connection, player_info):
|
||||||
s['jobstate'] = JobStates(connection, player_info)
|
s['jobstate'] = JobStates(connection, player_info)
|
||||||
s['jobstate'].run()
|
s['jobstate'].run()
|
||||||
|
|
||||||
|
|
||||||
def main(connection, player_info):
|
def main(connection, player_info):
|
||||||
def handle_join_game(join_game_packet):
|
def handle_join_game(join_game_packet):
|
||||||
print('Connected.')
|
print('Connected.')
|
||||||
|
@ -850,11 +1217,11 @@ def main(connection, player_info):
|
||||||
connection.register_packet_listener(
|
connection.register_packet_listener(
|
||||||
x, clientbound.play.BlockChangePacket)
|
x, clientbound.play.BlockChangePacket)
|
||||||
|
|
||||||
#def y(p):
|
def handle_time_update(p):
|
||||||
# print(p)
|
s['time'] = p.time_of_day % 24000
|
||||||
|
|
||||||
#connection.register_packet_listener(
|
connection.register_packet_listener(
|
||||||
# y, AcknowledgePlayerDiggingPacket)
|
handle_time_update, custom_packets.TimeUpdatePacket)
|
||||||
|
|
||||||
def handle_set_slot(p):
|
def handle_set_slot(p):
|
||||||
print(p)
|
print(p)
|
||||||
|
@ -872,6 +1239,9 @@ def main(connection, player_info):
|
||||||
if '!reload' in chat_packet.json_data:
|
if '!reload' in chat_packet.json_data:
|
||||||
global running
|
global running
|
||||||
running = False
|
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:
|
elif '!afk' in chat_packet.json_data:
|
||||||
say(connection, '/afk')
|
say(connection, '/afk')
|
||||||
elif '!respawn' in chat_packet.json_data:
|
elif '!respawn' in chat_packet.json_data:
|
||||||
|
@ -919,11 +1289,29 @@ def main(connection, player_info):
|
||||||
for i in player_info.inv.values():
|
for i in player_info.inv.values():
|
||||||
if i.present:
|
if i.present:
|
||||||
print(items.ITEM_NAMES[i.item_id], 'x', i.item_count)
|
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:
|
elif '!echo' in chat_packet.json_data:
|
||||||
parts = chat_packet.json_data.split('\'')
|
parts = chat_packet.json_data.split('\'')
|
||||||
say(connection, parts[1])
|
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:
|
elif 'get wood and survive' in chat_packet.json_data:
|
||||||
for i in player_info.inv.values():
|
for i in player_info.inv.values():
|
||||||
|
print(i.item_id)
|
||||||
if i.item_id in items.BED_IDS:
|
if i.item_id in items.BED_IDS:
|
||||||
break
|
break
|
||||||
else: # for
|
else: # for
|
||||||
|
@ -932,8 +1320,21 @@ def main(connection, player_info):
|
||||||
|
|
||||||
s['jobstate'].state = s['jobstate'].lumberjack
|
s['jobstate'].state = s['jobstate'].lumberjack
|
||||||
s['jobstate'].survive = True
|
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:
|
elif 'get wood' in chat_packet.json_data:
|
||||||
s['jobstate'].state = s['jobstate'].lumberjack
|
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:
|
elif 'stop job' in chat_packet.json_data:
|
||||||
say(connection, 'ok')
|
say(connection, 'ok')
|
||||||
s['jobstate'].state = s['jobstate'].stop
|
s['jobstate'].state = s['jobstate'].stop
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import minecraft.networking.packets
|
import minecraft.networking.packets
|
||||||
|
|
||||||
from minecraft.networking.packets import Packet
|
from minecraft.networking.packets import Packet
|
||||||
from minecraft.networking.types import BlockFace, VarInt, Position, Boolean, Byte, UnsignedByte, Short, TrailingByteArray
|
from minecraft.networking.types import BlockFace, VarInt, Position, Boolean, Byte, UnsignedByte, Short, TrailingByteArray, Long
|
||||||
from minecraft.networking.types.basic import Type
|
from minecraft.networking.types.basic import Type
|
||||||
|
|
||||||
#def qot(x):
|
#def qot(x):
|
||||||
|
@ -15,9 +15,9 @@ class AcknowledgePlayerDiggingPacket(Packet):
|
||||||
id = 0x08
|
id = 0x08
|
||||||
packet_name = 'acknowledge player digging'
|
packet_name = 'acknowledge player digging'
|
||||||
definition = [
|
definition = [
|
||||||
{'status': VarInt},
|
|
||||||
{'location': Position},
|
{'location': Position},
|
||||||
{'face': VarInt},
|
{'block': VarInt},
|
||||||
|
{'status': VarInt},
|
||||||
{'successful': Boolean},
|
{'successful': Boolean},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -72,8 +72,6 @@ class Slot(Type):
|
||||||
# TODO
|
# TODO
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SetSlotPacket(Packet):
|
class SetSlotPacket(Packet):
|
||||||
id = 0x17
|
id = 0x17
|
||||||
packet_name = 'set slot'
|
packet_name = 'set slot'
|
||||||
|
@ -83,6 +81,14 @@ class SetSlotPacket(Packet):
|
||||||
{'slot_data': Slot},
|
{'slot_data': Slot},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
class TimeUpdatePacket(Packet):
|
||||||
|
id = 0x4F
|
||||||
|
packet_name = 'time update'
|
||||||
|
definition = [
|
||||||
|
{'world_age': Long},
|
||||||
|
{'time_of_day': Long},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -93,6 +99,7 @@ def get_packets(old_get_packets):
|
||||||
packets.add(AcknowledgePlayerDiggingPacket)
|
packets.add(AcknowledgePlayerDiggingPacket)
|
||||||
packets.add(BlockBreakAnimationPacket)
|
packets.add(BlockBreakAnimationPacket)
|
||||||
packets.add(SetSlotPacket)
|
packets.add(SetSlotPacket)
|
||||||
|
packets.add(TimeUpdatePacket)
|
||||||
return packets
|
return packets
|
||||||
return lambda x: wrapper(old_get_packets, x)
|
return lambda x: wrapper(old_get_packets, x)
|
||||||
|
|
||||||
|
@ -129,3 +136,14 @@ class PickItemPacket(Packet):
|
||||||
definition = [
|
definition = [
|
||||||
{'slot_to_use': VarInt},
|
{'slot_to_use': VarInt},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
class HeldItemChangePacket(Packet):
|
||||||
|
# Sent when the player changes the slot selection
|
||||||
|
# https://wiki.vg/Protocol#Held_Item_Change_.28serverbound.29
|
||||||
|
|
||||||
|
id = 0x23
|
||||||
|
packet_name = 'held item change'
|
||||||
|
|
||||||
|
definition = [
|
||||||
|
{'slot': Short},
|
||||||
|
]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user