import re import time import importlib from math import hypot from panda3d.core import LPoint3f from minecraft.networking.types import BlockFace 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 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 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.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) def tick(self): self.state()