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 importlib.reload(utils) import path importlib.reload(path) import blocks importlib.reload(blocks) import items importlib.reload(items) import mcdata importlib.reload(mcdata) import mobs importlib.reload(mobs) class SellToVillagerStates: def idle(self): return None def init(self): self.trade = None self.state = self.find_villager def find_villager(self): print('Finding new villager...') w = self.g.world p = utils.pint(self.g.pos) for v in w.find_villagers(p, 100): print('Found villager:', v) if v not in self.bad_villagers and v not in self.spent_villagers: break else: # for print('No good villagers left, aborting.') self.spent_villagers = [] self.state = self.cleanup return self.villager = v self.villager_pos = utils.pint((v.x, v.y, v.z)) self.state = self.find_openings def find_openings(self): w = self.g.world self.openings = w.find_villager_openings(self.villager_pos) 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 villager:', self.villager) if self.villager not in self.good_villagers: self.bad_villagers.append(self.villager) print('Added to bad villager list') 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_villager else: self.openings.pop(0) def going_to_villager(self): if utils.pint(self.g.pos) == self.openings[0]: print('Arrived at villager') self.g.look_at = self.villager_pos self.wait_time = 0.5 self.state = self.wait_to_interact def wait_to_interact(self): if self.wait_time > 0: self.wait_time -= utils.TICK else: self.state = self.interact_villager def interact_villager(self): print('Interacting with villager') self.g.game.interact(self.villager.entity_id) self.g.game.animate() self.wait_time = 0.5 self.state = self.wait_for_window def wait_for_window(self): if self.wait_time > 0: self.wait_time -= utils.TICK else: self.state = self.choose_trade def choose_trade(self): g = self.g.game w = self.g.window if not w or not self.g.trades: print('Didnt get a trade window, aborting') self.state = self.cleanup return if w.data.window_type != mcdata.VILLAGER_TRADE: print('Got wrong window, aborting') self.state = self.cleanup return for trade_num, trade in enumerate(self.g.trades): in_id = trade.input_item_1.item_id in_num = trade.input_item_1.item_count out_id = trade.output_item.item_id price = in_num \ + floor(in_num * trade.price_multiplier * trade.demand) \ + trade.special_price if price < 1: price = 1 if g.count_items([in_id]) < price: continue print('Checking trade #', trade_num) if trade.trade_disabled: print('Trade disabled, skipping') continue if out_id != items.EMERALD_ID: print('Not for emeralds, skipping') continue if price > in_num: print('Trade in demand, skipping') continue print('Found trade:', trade) print('Adjusted price:', price) self.trade = trade self.trade_num = trade_num self.state = self.click_trade break else: print('Villager has been spent, aborting') self.g.game.close_window() self.spent_villagers.append(self.villager) self.state = self.wait self.wait_time = 10 return def click_trade(self): print('Clicking trade') self.g.item_lock = True self.g.game.select_trade(self.trade_num) self.state = self.execute_trade def execute_trade(self): if self.g.item_lock: return w = self.g.window w_info = mcdata.WINDOWS[w.data.window_type] slot_num = w_info.output if slot_num in w.contents: print('Executing trade') slot = w.contents[slot_num] self.g.game.click_window(slot_num, 0, 1, slot) else: print('Bad trade, aborting') self.state = self.end_trade def end_trade(self): print('Trading complete') self.g.game.close_window() self.wait_time = 1 self.state = self.wait_for_trade def wait_for_trade(self): if self.wait_time > 0: self.wait_time -= utils.TICK else: self.state = self.interact_villager def wait(self): if self.wait_time > 0: self.wait_time -= utils.TICK else: self.state = self.cleanup 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.villager = None self.villager_pos = None self.bad_villagers = [] self.good_villagers = [] self.spent_villagers = [] self.openings = [] self.trade = None self.wait_time = 0 def run(self): self.state()