feat(skill): inventory
This commit is contained in:
@@ -1,14 +1,13 @@
|
||||
import type { Bot } from 'mineflayer'
|
||||
import type { SkillContext } from './base'
|
||||
import pathfinderModel from 'mineflayer-pathfinder'
|
||||
import * as world from '../composables/world'
|
||||
import { log } from './base'
|
||||
import { goToPosition } from './movement'
|
||||
|
||||
/**
|
||||
* Pick up nearby items
|
||||
*/
|
||||
const { goals } = pathfinderModel
|
||||
|
||||
export async function pickupNearbyItems(ctx: SkillContext): Promise<boolean> {
|
||||
const { bot } = ctx
|
||||
const distance = 8
|
||||
const getNearestItem = (bot: Bot) =>
|
||||
bot.nearestEntity(entity =>
|
||||
@@ -16,15 +15,15 @@ export async function pickupNearbyItems(ctx: SkillContext): Promise<boolean> {
|
||||
&& bot.entity.position.distanceTo(entity.position) < distance,
|
||||
)
|
||||
|
||||
let nearestItem = getNearestItem(bot)
|
||||
let nearestItem = getNearestItem(ctx.bot)
|
||||
let pickedUp = 0
|
||||
|
||||
while (nearestItem) {
|
||||
await bot.pathfinder.goto(bot.pathfinder.goals.GoalFollow(nearestItem, 0.8), true)
|
||||
await ctx.bot.pathfinder.goto(new goals.GoalFollow(nearestItem, 0.8))
|
||||
await new Promise(resolve => setTimeout(resolve, 200))
|
||||
|
||||
const prev = nearestItem
|
||||
nearestItem = getNearestItem(bot)
|
||||
nearestItem = getNearestItem(ctx.bot)
|
||||
if (prev === nearestItem) {
|
||||
break
|
||||
}
|
||||
@@ -35,55 +34,47 @@ export async function pickupNearbyItems(ctx: SkillContext): Promise<boolean> {
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Equip an item
|
||||
*/
|
||||
export async function equip(ctx: SkillContext, itemName: string): Promise<boolean> {
|
||||
const { bot } = ctx
|
||||
const item = bot.inventory.slots.find(slot => slot && slot.name === itemName)
|
||||
const item = ctx.bot.inventory.slots.find(slot => slot && slot.name === itemName)
|
||||
if (!item) {
|
||||
log(ctx, `You do not have any ${itemName} to equip.`)
|
||||
return false
|
||||
}
|
||||
|
||||
if (itemName.includes('leggings')) {
|
||||
await bot.equip(item, 'legs')
|
||||
await ctx.bot.equip(item, 'legs')
|
||||
}
|
||||
else if (itemName.includes('boots')) {
|
||||
await bot.equip(item, 'feet')
|
||||
await ctx.bot.equip(item, 'feet')
|
||||
}
|
||||
else if (itemName.includes('helmet')) {
|
||||
await bot.equip(item, 'head')
|
||||
await ctx.bot.equip(item, 'head')
|
||||
}
|
||||
else if (itemName.includes('chestplate') || itemName.includes('elytra')) {
|
||||
await bot.equip(item, 'torso')
|
||||
await ctx.bot.equip(item, 'torso')
|
||||
}
|
||||
else if (itemName.includes('shield')) {
|
||||
await bot.equip(item, 'off-hand')
|
||||
await ctx.bot.equip(item, 'off-hand')
|
||||
}
|
||||
else {
|
||||
await bot.equip(item, 'hand')
|
||||
await ctx.bot.equip(item, 'hand')
|
||||
}
|
||||
|
||||
log(ctx, `Equipped ${itemName}.`)
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Discard items
|
||||
*/
|
||||
export async function discard(ctx: SkillContext, itemName: string, num = -1): Promise<boolean> {
|
||||
const { bot } = ctx
|
||||
let discarded = 0
|
||||
|
||||
while (true) {
|
||||
const item = bot.inventory.items().find(item => item.name === itemName)
|
||||
const item = ctx.bot.inventory.items().find(item => item.name === itemName)
|
||||
if (!item) {
|
||||
break
|
||||
}
|
||||
|
||||
const toDiscard = num === -1 ? item.count : Math.min(num - discarded, item.count)
|
||||
await bot.toss(item.type, null, toDiscard)
|
||||
await ctx.bot.toss(item.type, null, toDiscard)
|
||||
discarded += toDiscard
|
||||
|
||||
if (num !== -1 && discarded >= num) {
|
||||
@@ -100,18 +91,14 @@ export async function discard(ctx: SkillContext, itemName: string, num = -1): Pr
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Put items in a chest
|
||||
*/
|
||||
export async function putInChest(ctx: SkillContext, itemName: string, num = -1): Promise<boolean> {
|
||||
const { bot } = ctx
|
||||
const chest = world.getNearestBlock(bot, 'chest', 32)
|
||||
const chest = world.getNearestBlock(world.createWorldContext(ctx.botCtx), 'chest', 32)
|
||||
if (!chest) {
|
||||
log(ctx, 'Could not find a chest nearby.')
|
||||
return false
|
||||
}
|
||||
|
||||
const item = bot.inventory.items().find(item => item.name === itemName)
|
||||
const item = ctx.bot.inventory.items().find(item => item.name === itemName)
|
||||
if (!item) {
|
||||
log(ctx, `You do not have any ${itemName} to put in the chest.`)
|
||||
return false
|
||||
@@ -120,7 +107,7 @@ export async function putInChest(ctx: SkillContext, itemName: string, num = -1):
|
||||
const toPut = num === -1 ? item.count : Math.min(num, item.count)
|
||||
await goToPosition(ctx, chest.position.x, chest.position.y, chest.position.z, 2)
|
||||
|
||||
const chestContainer = await bot.openContainer(chest)
|
||||
const chestContainer = await ctx.bot.openContainer(chest)
|
||||
await chestContainer.deposit(item.type, null, toPut)
|
||||
await chestContainer.close()
|
||||
|
||||
@@ -128,19 +115,15 @@ export async function putInChest(ctx: SkillContext, itemName: string, num = -1):
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Take items from a chest
|
||||
*/
|
||||
export async function takeFromChest(ctx: SkillContext, itemName: string, num = -1): Promise<boolean> {
|
||||
const { bot } = ctx
|
||||
const chest = world.getNearestBlock(bot, 'chest', 32)
|
||||
const chest = world.getNearestBlock(world.createWorldContext(ctx.botCtx), 'chest', 32)
|
||||
if (!chest) {
|
||||
log(ctx, 'Could not find a chest nearby.')
|
||||
return false
|
||||
}
|
||||
|
||||
await goToPosition(ctx, chest.position.x, chest.position.y, chest.position.z, 2)
|
||||
const chestContainer = await bot.openContainer(chest)
|
||||
const chestContainer = await ctx.bot.openContainer(chest)
|
||||
|
||||
const item = chestContainer.containerItems().find(item => item.name === itemName)
|
||||
if (!item) {
|
||||
@@ -157,19 +140,15 @@ export async function takeFromChest(ctx: SkillContext, itemName: string, num = -
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* View contents of a chest
|
||||
*/
|
||||
export async function viewChest(ctx: SkillContext): Promise<boolean> {
|
||||
const { bot } = ctx
|
||||
const chest = world.getNearestBlock(bot, 'chest', 32)
|
||||
const chest = world.getNearestBlock(world.createWorldContext(ctx.botCtx), 'chest', 32)
|
||||
if (!chest) {
|
||||
log(ctx, 'Could not find a chest nearby.')
|
||||
return false
|
||||
}
|
||||
|
||||
await goToPosition(ctx, chest.position.x, chest.position.y, chest.position.z, 2)
|
||||
const chestContainer = await bot.openContainer(chest)
|
||||
const chestContainer = await ctx.bot.openContainer(chest)
|
||||
const items = chestContainer.containerItems()
|
||||
|
||||
if (items.length === 0) {
|
||||
@@ -186,16 +165,12 @@ export async function viewChest(ctx: SkillContext): Promise<boolean> {
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume (eat/drink) an item
|
||||
*/
|
||||
export async function consume(ctx: SkillContext, itemName = ''): Promise<boolean> {
|
||||
const { bot } = ctx
|
||||
let item
|
||||
let name
|
||||
|
||||
if (itemName) {
|
||||
item = bot.inventory.items().find(item => item.name === itemName)
|
||||
item = ctx.bot.inventory.items().find(item => item.name === itemName)
|
||||
name = itemName
|
||||
}
|
||||
|
||||
@@ -204,23 +179,19 @@ export async function consume(ctx: SkillContext, itemName = ''): Promise<boolean
|
||||
return false
|
||||
}
|
||||
|
||||
await bot.equip(item, 'hand')
|
||||
await bot.consume()
|
||||
await ctx.bot.equip(item, 'hand')
|
||||
await ctx.bot.consume()
|
||||
log(ctx, `Consumed ${item.name}.`)
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Give items to a player
|
||||
*/
|
||||
export async function giveToPlayer(
|
||||
ctx: SkillContext,
|
||||
itemType: string,
|
||||
username: string,
|
||||
num = 1,
|
||||
): Promise<boolean> {
|
||||
const { bot } = ctx
|
||||
const player = bot.players[username]?.entity
|
||||
const player = ctx.bot.players[username]?.entity
|
||||
if (!player) {
|
||||
log(ctx, `Could not find ${username}.`)
|
||||
return false
|
||||
@@ -228,21 +199,21 @@ export async function giveToPlayer(
|
||||
|
||||
await goToPosition(ctx, player.position.x, player.position.y, player.position.z, 3)
|
||||
|
||||
if (bot.entity.position.y < player.position.y - 1) {
|
||||
if (ctx.bot.entity.position.y < player.position.y - 1) {
|
||||
await goToPosition(ctx, player.position.x, player.position.y, player.position.z, 1)
|
||||
}
|
||||
|
||||
if (bot.entity.position.distanceTo(player.position) < 2) {
|
||||
const goal = bot.pathfinder.goals.GoalNear(player.position.x, player.position.y, player.position.z, 2)
|
||||
const invertedGoal = bot.pathfinder.goals.GoalInvert(goal)
|
||||
await bot.pathfinder.goto(invertedGoal)
|
||||
if (ctx.bot.entity.position.distanceTo(player.position) < 2) {
|
||||
const goal = new goals.GoalNear(player.position.x, player.position.y, player.position.z, 2)
|
||||
const invertedGoal = new goals.GoalInvert(goal)
|
||||
await ctx.bot.pathfinder.goto(invertedGoal)
|
||||
}
|
||||
|
||||
await bot.lookAt(player.position)
|
||||
await ctx.bot.lookAt(player.position)
|
||||
|
||||
if (await discard(ctx, itemType, num)) {
|
||||
let given = false
|
||||
bot.once('playerCollect', (collector, collected) => {
|
||||
ctx.bot.once('playerCollect', (collector, _collected) => {
|
||||
if (collector.username === username) {
|
||||
log(ctx, `${username} received ${itemType}.`)
|
||||
given = true
|
||||
|
||||
Reference in New Issue
Block a user