import re import time import importlib import random from itertools import count from math import hypot, floor from minecraft.networking.types import BlockFace from mosfet.protocol.managers import ChunkNotLoadedException from mosfet import utils from mosfet import path from mosfet.info import blocks from mosfet.info import items from mosfet.info import mcdata from mosfet.info import mobs class CacheItemsStates: def idle(self): return None def init(self): self.skip_slots = [] self.skip_items = [] num_stacks = self.g.game.count_inventory_slots() print('Inventory amount:', num_stacks) if num_stacks >= self.g.minimum_cache_slots: self.state = self.find_trapped_chests else: print('Aborting caching, not full') self.state = self.cleanup def find_trapped_chests(self): print('Finding trapped chests...') w = self.g.world p = utils.pint(self.g.pos) self.trapped_chests = w.find_blocks_indexed(p, blocks.TRAPPED_CHEST_IDS) print('Found:', self.trapped_chests) self.state = self.choose_trapped_chest def choose_trapped_chest(self): print('Choosing a trapped chest...') w = self.g.world p = utils.pint(self.g.pos) c = self.g.chunks if not len(self.trapped_chests): print('No trapped chests') self.state = self.select_chest return chest = self.trapped_chests[0] navpath = w.path_to_place_faked(p, chest) print('navpath:', navpath) if navpath: self.g.path = navpath[:-1] self.opening = self.g.path[-1] self.area = chest self.state = self.going_to_trapped_chest return else: self.trapped_chests.pop(0) def going_to_trapped_chest(self): if utils.pint(self.g.pos) == self.opening: self.g.look_at = self.area self.state = self.open_chest def select_chest(self): if self.g.game.select_item([items.CHEST_ID]): self.state = self.find_cache_spot else: print('No chest, aborting') self.state = self.cleanup def find_cache_spot(self): print('Finding a chest spot...') w = self.g.world p = utils.pint(self.g.pos) for area in w.find_cache_areas(p, 100): print('Found area:', area) if area not in self.bad_areas: break else: # for print('Unable to find area') self.state = self.cleanup return self.area = area openings = w.find_cache_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 def going_to_area(self): if utils.pint(self.g.pos) == self.opening: self.g.look_at = self.area self.state = self.place_chest 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 if not w: print('Didnt get a window, aborting') self.state = self.cleanup return if w.data.window_type != mcdata.SINGLE_CHEST: print('Got wrong window, aborting') self.state = self.cleanup return w_info = mcdata.WINDOWS[w.data.window_type] w_inventory_slots = w_info.inventory w_container_slots = w_info.container used_slots = self.g.game.count_window_slots() print('used:', used_slots, 'total:', len(w_container_slots)) if used_slots >= len(w_container_slots): print('Container is too full, aborting') self.g.game.close_window() self.g.look_at = None self.state = self.cleanup return slot_list = [] 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.NEEDED_ITEMS: continue if slot_num in self.skip_slots: continue slot_list.append((slot_num, slot)) slot_list.sort(key=lambda x: x[1].item_count, reverse=True) for slot_num, slot in slot_list: if slot.item_id in items.WANTED_ITEMS and slot.item_id not in self.skip_items: print('skipping wanted item', slot) self.skip_slots.append(slot_num) self.skip_items.append(slot.item_id) continue print('moving', slot) 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() if not self.silent: 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.silent = False self.skip_slots = [] self.skip_items = [] self.area = None self.opening = None self.trapped_chests = [] self.bad_areas = [] self.wait_time = 0 def run(self): self.state()