import re import time import importlib import random from itertools import count from math import hypot, floor from minecraft.networking.types import BlockFace from protocol.managers import ChunkNotLoadedException import utils import path import blocks import items import mcdata import mobs class GrabSuppliesStates: def idle(self): return None def init(self): print('Started grab supplies states') self.checked_barrels = [] used_slots = self.g.game.count_inventory_slots() print('used:', used_slots, 'total:', self.g.maximum_supply_slots) if used_slots >= self.g.maximum_supply_slots: print('Inventory is too full, aborting') self.state = self.cleanup return if self.supplies: self.state = self.check_supplies else: print('Aborting getting supplies, none specified') self.state = self.cleanup def check_supplies(self): # check if we need to grab anything for items, limits in self.supplies.items(): minimum, maximum = limits print('Checking items:', items) num_items = self.g.game.count_items(items) print('Have:', num_items) if num_items >= minimum: print('Have enough, skipping') continue print('Need at least one item') self.state = self.find_barrels return print('Aborting, dont need any supplies') self.state = self.cleanup def find_barrels(self): print('Finding barrels...') w = self.g.world p = utils.pint(self.g.pos) self.barrels = w.find_blocks_indexed(p, blocks.BARREL_IDS) print('Found:', self.barrels) self.state = self.choose_barrel def choose_barrel(self): print('Choosing a barrel...') for barrel in self.barrels: if barrel in self.checked_barrels: continue if barrel in self.bad_barrels: continue self.barrel = barrel self.state = self.path_to_barrel return print('No barrels') self.state = self.cleanup def path_to_barrel(self): print('Finding path to barrel') w = self.g.world p = utils.pint(self.g.pos) c = self.g.chunks barrel = self.barrel tmp = c.get_block_at(*barrel) c.set_block_at(*barrel, blocks.AIR) navpath = w.path_to_place(p, barrel) c.set_block_at(*barrel, tmp) print('navpath:', navpath) if navpath: self.g.path = navpath[:-1] self.opening = self.g.path[-1] self.checked_barrels.append(barrel) self.area = barrel self.state = self.going_to_barrel self.checked_supplies = [] return else: print('No path, blacklisting barrel') self.bad_barrels.append(barrel) self.state = self.choose_barrel def going_to_barrel(self): if utils.pint(self.g.pos) == self.opening: self.g.look_at = self.area self.state = self.open_barrel def open_barrel(self): print('Opening barrel') self.g.game.open_container(self.area) self.wait_time = 1 self.state = self.wait def wait(self): # wait for server to send us inventory contents if self.wait_time > 0: self.wait_time -= utils.TICK else: self.state = self.choose_items def choose_items(self): print('Selecting next item') for items, limits in self.supplies.items(): minimum_items, maximum_stacks = limits print('Checking items:', items) num_items = self.g.game.count_items(items) print('Have:', num_items) if num_items >= minimum_items: print('Have enough, skipping') continue if items in self.checked_supplies: print('Already checked, skipping') continue print('Need some') self.checked_supplies.append(items) self.target_items = items self.maximum_stacks = maximum_stacks self.count = 0 self.state = self.grab_items return print('Aborting, dont need any more supplies') self.state = self.close_barrel def grab_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 used_slots = self.g.game.count_inventory_slots() print('used:', used_slots, 'total:', self.g.maximum_supply_slots) if used_slots >= self.g.maximum_supply_slots: print('Inventory is too full, aborting') self.g.game.close_window() self.g.look_at = None self.state = self.cleanup return w_info = mcdata.WINDOWS[w.data.window_type] w_container_slots = w_info.container for slot_num in w_container_slots: if slot_num not in w.contents: continue slot = w.contents[slot_num] if not slot.present: continue if slot.item_id not in self.target_items: continue if self.maximum_stacks and self.count >= self.maximum_stacks: break self.count += 1 print('Moving', slot) self.g.item_lock = True self.g.game.click_window(slot_num, 0, 1, slot) return print('None left to move') self.wait_time = 0.25 self.state = self.wait def close_barrel(self): print('Closing barrel') self.g.game.close_window() self.g.look_at = None self.state = self.choose_barrel def cleanup(self): 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.supplies = {} self.barrels = [] self.checked_barrels = [] self.bad_barrels = [] self.barrel = None self.checked_supplies = [] self.target_items = None self.maximum_stacks = 0 self.count = 0 self.area = None self.opening = None self.wait_time = 0 def run(self): self.state()