import re import time import importlib from math import hypot from panda3d.core import LPoint3f from minecraft.networking.types import BlockFace from protocol.managers import ChunkNotLoadedException import utils importlib.reload(utils) import path importlib.reload(path) import blocks importlib.reload(blocks) import items importlib.reload(items) import data importlib.reload(data) class FindGappleStates: def idle(self): return None def init(self): self.state = self.go_spectator def go_spectator(self): print('Going spectator...') self.g.chat.send('/gamemode spectator') self.state = self.tp_to_coord def tp_to_coord(self): step = utils.spiral(self.count) step_scaled = utils.pmul(step, 192) self.coord = utils.padd(self.origin, step_scaled) self.coord = utils.padd(self.coord, (0, 50, 0)) print('count:', self.count, 'teleporting to:', self.coord) self.g.chat.send('/tp {} {} {}'.format(*self.coord)) self.state = self.wait_for_load def wait_for_load(self): if self.g.chunks.check_loaded(self.g.pos): print('chunks have been loaded') self.state = self.pick_chest def pick_chest(self): chest_list = [] for chest_id in blocks.CHEST_IDS: chest_list.extend(self.g.chunks.index.get(chest_id, [])) for chest in chest_list: if chest in self.checked_chests: continue self.current_chest = chest self.state = self.break_chest break else: # for print('exhausted chest list') self.state = self.cleanup def break_chest(self): print('Breaking chest', self.current_chest) self.g.command_lock = True self.g.chat.send('/setblock {} {} {} air destroy'.format(*self.current_chest)) self.checked_chests.append(self.current_chest) self.state = self.wait_for_items def wait_for_items(self): if not self.g.command_lock: print('done waiting for items') self.state = self.pick_chest def cleanup(self): self.count += 1 self.state = self.done def done(self): # never gets ran, placeholder return None def __init__(self, global_state): self.g = global_state self.state = self.idle self.origin = utils.pint(self.g.pos) self.count = 0 self.coord = None self.current_chest = None self.checked_chests = [] def run(self): self.state() class LumberjackStates: def bair(self, p): return self.g.chunks.get_block_at(*p) in blocks.NON_SOLID_IDS def blog(self, p): return self.g.chunks.get_block_at(*p) in blocks.LOG_IDS def idle(self): return None def init(self): self.state = self.find_new_tree def find_new_tree(self): print('Finding new tree...') w = self.g.world p = utils.pint(self.g.pos) trees = w.find_trees(p, 100) print('Found trees:', trees) while trees[0] in self.bad_trees: trees.pop(0) self.tree = trees[0] self.openings = w.find_tree_openings(self.tree) self.state = self.choose_opening def choose_opening(self): w = self.g.world p = utils.pint(self.g.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.cleanup return navpath = w.path_to_place(p, self.openings[0]) if navpath: self.g.path = navpath self.state = self.going_to_tree else: self.openings.pop(0) def going_to_tree(self): if utils.pint(self.g.pos) == self.openings[0]: self.g.look_at = self.tree self.state = self.clear_leaves def clear_leaves(self): if not self.g.breaking: p = utils.pint(self.g.pos) diff = utils.psub(self.tree, p) for x in utils.diffrange(diff[0]): for z in utils.diffrange(diff[2]): for y in range(2): check = utils.padd(p, (x, y, z)) if check == self.tree: break if not self.bair(check): print('Breaking leaf') self.g.game.break_block(check) return self.state = self.clear_trunk_base def clear_trunk_base(self): if not self.g.breaking: base = self.tree above = utils.padd(self.tree, path.BLOCK_ABOVE) if self.blog(base): self.g.game.break_block(base) print('breaking base') elif self.blog(above): self.g.game.break_block(above) print('breaking above') else: w = self.g.world p = utils.pint(self.g.pos) navpath = w.path_to_place(p, self.tree) if navpath: self.g.path = navpath self.state = self.going_to_trunk_base else: self.openings.pop(0) self.state = self.choose_opening def going_to_trunk_base(self): if utils.pint(self.g.pos) == self.tree: self.g.look_at = utils.padd(self.tree, path.BLOCK_ABOVE2) self.state = self.clear_trunk def clear_trunk(self): if not self.g.breaking: check = self.tree count = 0 while self.bair(check) and count < 6: check = utils.padd(check, path.BLOCK_ABOVE) count += 1 if self.blog(check): print('breaking log', check) self.g.game.break_block(check) else: print('Finished clearing tree') self.wait_time = 0.5 self.state = self.wait def wait(self): # wait for the last log to fall if self.wait_time > 0: self.wait_time -= utils.TICK else: self.state = self.cleanup def cleanup(self): self.g.look_at = None self.state = self.done def done(self): # never gets ran, placeholder return None def __init__(self, global_state): self.g = global_state self.state = self.idle self.tree = None self.openings = [] self.bad_trees = [] self.wait_time = 0 def run(self): self.state() class GatherSandStates: def bair(self, p): return self.g.chunks.get_block_at(*p) in blocks.NON_SOLID_IDS def bsand(self, p): return self.g.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 = self.g.world p = utils.pint(self.g.pos) sand = w.find_sand(p, 50, self.origin) print('Found sand:', sand) for check in sand: if check in self.bad_sand: continue self.sand = check break self.state = self.nav_to_sand def nav_to_sand(self): w = self.g.world p = utils.pint(self.g.pos) self.g.chunks.set_block_at(*self.sand, blocks.AIR) navpath = w.path_to_place(p, self.sand) self.g.chunks.set_block_at(*self.sand, blocks.SAND) if navpath: self.g.path = navpath[:-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(self.g.path): self.g.look_at = self.sand self.state = self.dig_sand def dig_sand(self): if not self.g.breaking: if self.bsand(self.sand): self.g.game.break_block(self.sand) print('digging sand') else: self.state = self.get_sand def get_sand(self): w = self.g.world p = utils.pint(self.g.pos) navpath = w.path_to_place(p, self.sand) if navpath: self.g.path = navpath 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 utils.pint(self.g.pos) == self.sand: self.g.look_at = self.sand self.state = self.cleanup def cleanup(self): self.g.look_at = None self.state = self.done def done(self): # never gets ran, placeholder return None def __init__(self, global_state): self.g = global_state self.state = self.idle self.origin = utils.pint(self.g.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 self.g.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 = self.g.world p = utils.pint(self.g.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: navpath = w.path_to_place(p, o) self.opening = o if navpath: break else: # for print('Unable to get to bed area', self.area) self.bad_areas.append(self.area) self.state = self.cleanup return self.g.path = navpath self.state = self.going_to_area self.last_area = self.area def going_to_area(self): if utils.pint(self.g.pos) == self.opening: self.g.look_at = self.area self.state = self.select_bed def select_bed(self): if self.g.game.select_item(items.BED_IDS): self.g.look_at = utils.padd(self.area, path.BLOCK_BELOW) self.state = self.place_bed else: self.g.chat.send('I need a bed') self.state = self.cleanup def place_bed(self): self.g.game.place_block(self.area, BlockFace.TOP) self.state = self.use_bed def use_bed(self): if self.g.time >= 12542: print('Sleeping') self.g.game.place_block(self.area, BlockFace.TOP) self.g.chat.send('zzz') self.state = self.sleep_bed def sleep_bed(self): if self.g.time < 100: print('Woke up') self.state = self.break_bed def break_bed(self): self.g.game.break_block(self.area) self.state = self.collect_bed def collect_bed(self): if not self.g.breaking: self.g.path = [utils.padd(self.area, utils.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 -= utils.TICK else: self.state = self.cleanup def cleanup(self): self.g.look_at = None self.state = self.done def done(self): # never gets ran, placeholder return None def __init__(self, global_state): self.g = global_state 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 CacheItemsStates: def idle(self): return None def init(self): num_stacks = len([x for x in self.g.inv.values() if x.present]) print('inventory amount:', num_stacks) if num_stacks >= 27: self.state = self.find_cache_spot else: print('Aborting caching, not full') self.state = self.cleanup def find_cache_spot(self): print('Finding a chest spot...') w = self.g.world p = utils.pint(self.g.pos) areas = w.find_cache_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: navpath = w.path_to_place(p, o) self.opening = o if navpath: break else: # for print('Unable to get to cache area', self.area) self.bad_areas.append(self.area) self.state = self.cleanup return self.g.path = navpath self.state = self.going_to_area self.last_area = self.area def going_to_area(self): if utils.pint(self.g.pos) == self.opening: self.g.look_at = self.area self.state = self.select_chest def select_chest(self): if self.g.game.select_item(items.CHEST_ID): self.g.look_at = utils.padd(self.area, path.BLOCK_BELOW) self.state = self.place_chest else: self.g.chat.send('I need a chest') self.state = self.cleanup def place_chest(self): self.g.game.place_block(self.area, BlockFace.TOP) self.state = self.open_chest def open_chest(self): print('Opening chest') self.g.game.open_container(self.area) self.wait_time = 1 self.state = self.wait def wait(self): # wait for server to send us chest contents if self.wait_time > 0: self.wait_time -= utils.TICK else: self.state = self.move_items def move_items(self): if self.g.item_lock: return w = self.g.window w_info = data.WINDOWS[w.data.window_type] w_inventory_slots = w_info.inventory for slot_num in w_inventory_slots: if slot_num not in w.contents: continue slot = w.contents[slot_num] if not slot.present: continue if slot.item_id in items.USEFUL_ITEMS: continue print('moving', slot) #inv_slot_num = slot_num - w_info.slot_diff #self.g.inv.pop(inv_slot_num, None) self.g.item_lock = True self.g.game.click_window(slot_num, 0, 1, slot) return print('nothing left to move') self.state = self.close_chest def close_chest(self): print('closing chest') self.g.game.close_window() self.g.chat.send('cache at ' + str(self.area)[1:-1]) self.state = self.cleanup def cleanup(self): self.g.look_at = None self.state = self.done def done(self): # never gets ran, placeholder return None def __init__(self, global_state): self.g = global_state 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 find_gapple(self): s1 = self.find_gapple_states if s1.state == s1.idle: s1.state = s1.init elif s1.state == s1.done: s1.state = s1.init s1.run() def gather_sand(self): s1 = self.gather_sand_states s2 = self.sleep_with_bed_states s3 = self.cache_items_states if s1.state == s1.idle: s1.state = s1.init s2.state = s2.init s3.state = s3.init elif s1.state == s1.done: if s2.state != s2.done: s2.run() return if s3.state != s3.done: s3.run() return s1.state = s1.init s2.state = s2.init s3.state = s3.init return s1.run() def lumberjack(self): s1 = self.lumberjack_states s2 = self.sleep_with_bed_states s3 = self.cache_items_states if s1.state == s1.idle: s1.state = s1.init s2.state = s2.init s3.state = s3.init elif s1.state == s1.done: if s2.state != s2.done: s2.run() return if s3.state != s3.done: s3.run() return s1.state = s1.init s2.state = s2.init s3.state = s3.init return s1.run() def stop(self): self.lumberjack_states = LumberjackStates(self.g) self.gather_sand_states = GatherSandStates(self.g) self.sleep_with_bed_states = SleepWithBedStates(self.g) self.cache_items_states = CacheItemsStates(self.g) self.find_gapple_states = FindGappleStates(self.g) self.state = self.idle def __init__(self, global_state): self.g = global_state self.state = self.idle self.prev_state = None self.lumberjack_states = LumberjackStates(self.g) self.gather_sand_states = GatherSandStates(self.g) self.sleep_with_bed_states = SleepWithBedStates(self.g) self.cache_items_states = CacheItemsStates(self.g) self.find_gapple_states = FindGappleStates(self.g) def tick(self): self.state()