import re import time import importlib import random from itertools import count from math import 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 EatFoodStates: def idle(self): return None def init(self): food = self.g.get('food') health = self.g.get('health') if food is None: print('No authoritative hunger status yet; not eating') self.state = self.cleanup return if food < 12: print('Hungry, eating') elif health is not None and health < 20 and food < 18: print('Low health, eating') else: print('Don\'t need to eat, aborting') self.state = self.cleanup return self.food_before = food self.saturation_before = self.g.get('food_saturation', 0.0) or 0.0 self.health_before = health self.selected_item_id = None self.selected_slot = None self.selected_count = 0 self.state = self.select_food def select_food(self): if not self.g.game.select_item(items.FOOD_IDS): print('No food, aborting') self.state = self.cleanup return self.selected_item_id = self.g.holding self.selected_slot = ( 45 if self.g.get('holding_hand', 0) == 1 else 36 + self.g.get('holding_slot', 0)) self.select_deadline = time.monotonic() + 2.0 self.state = self.wait_for_selection def wait_for_selection(self): selected = self.g.inv.get(self.selected_slot) if (selected and selected.present and selected.item_id == self.selected_item_id): self.selected_count = selected.item_count self.state = self.eat_food elif time.monotonic() >= self.select_deadline: print('Food did not reach the selected hand; aborting') self.state = self.cleanup def eat_food(self): hand = self.g.get('holding_hand', 0) print('Eating food from {} hand'.format( 'off' if hand else 'main')) self.g.game.use_item(hand) self.eat_deadline = time.monotonic() + 6.0 self.state = self.wait def wait(self): selected = self.g.inv.get(self.selected_slot) consumed = ( not selected or not selected.present or selected.item_id != self.selected_item_id or selected.item_count < self.selected_count) stats_improved = ( (self.g.get('food') is not None and self.g.food > self.food_before) or (self.g.get('food_saturation') is not None and self.g.food_saturation > self.saturation_before) or (self.health_before is not None and self.g.get('health') is not None and self.g.health > self.health_before)) if consumed or stats_improved: print('Eating confirmed by server state') self.state = self.cleanup elif time.monotonic() >= self.eat_deadline: print('Food use was not confirmed by server state') self.state = self.cleanup def cleanup(self): self.state = self.done if (self.g.get('job') and getattr(self.g.job.state, '__name__', None) == 'eat'): self.g.job.state = self.g.job.idle def done(self): # never gets ran, placeholder return None def __init__(self, global_state): self.g = global_state self.state = self.idle self.wait_time = 0 def run(self): self.state()