import { MAX_HEALTH, REGENERATE_FOOD, SPRINT_FOOD } from '../utils/constants' import Module from '../utils/Module' import Connection from './Connection' import Inventory from './Inventory' import Life from './Life' import State from './State' interface IConf { /** Life to regenerate */ targetHealth: number, /** Minimal food level */ minFood: number, /** Food level needed to regenerate */ regenerateFood: number, /** Food names by priority */ foods: string[] /** Food ids by priority (override foods) */ foodsIds?: number[] } export default class Meal extends Module { private life!: Life private inv!: Inventory private state!: State private _eating?: NodeJS.Timeout public get mustEat() { return this.life.food <= this.conf.minFood || (this.life.health <= this.conf.targetHealth && this.life.food <= this.conf.regenerateFood) } protected mount() { this.life = this.load(Life) this.inv = this.load(Inventory) this.state = this.load(State) const ready = () => { this.life.events.on('update', this.eat.bind(this)) this.client.on('entity_status', packet => { if (this._eating && packet.entityId === this.state.state.entityId && packet.entityStatus === 9) { clearInterval(this._eating) this._eating = undefined } }) this.eat() } if (this.conf.foodsIds) { ready() } else { this.load(Connection).data.onReady(data => { this.conf.foodsIds = this.conf.foods .map(name => data.items![name].numeric_id) ready() }) } } protected getConf() { return { minFood: SPRINT_FOOD, targetHealth: MAX_HEALTH, regenerateFood: REGENERATE_FOOD, foods: [ 'golden_carrot', 'cooked_porkchop', 'cooked_beef', 'rabbit_stew', 'cooked_mutton', 'cooked_salmon', // 'golden_apple', 'enchanted_golden_apple', 'beetroot_soup', 'cooked_chicken', 'mushroom_stem', 'baked_potato', 'bread', 'cooked_cod', 'cooked_rabbit', 'pumpkin_pie', 'carrot', 'apple', 'beef', 'porkchop', 'rabbit', 'honey_bottle', 'melon_slice', 'mutton', 'beetroot', 'dried_kelp', 'potato', 'cookie', 'cod', 'salmon', 'tropical_fish', 'chicken', 'rotten_flesh', ], } } private eat() { if (this.mustEat && !this._eating) { const food = this.inv.findFirst(this.conf.foodsIds!) if (food.slot >= 0) { this.logger.info('Eating %s', this.conf.foods[food.value]) this.inv.useItem(food.slot) this._eating = setTimeout(() => { this.logger.error('Fail eating') this._eating = undefined this.eat() }, 3000) } else { this.logger.warn('No food available') } } } }