Files
minecraft-bot/mosfet/jobs/eat_food.py
T

118 lines
3.7 KiB
Python

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()