|
|
async function killMob(bot, mobName, timeout = 300) { |
|
|
|
|
|
if (typeof mobName !== "string") { |
|
|
throw new Error(`mobName for killMob must be a string`); |
|
|
} |
|
|
|
|
|
if (typeof timeout !== "number") { |
|
|
throw new Error(`timeout for killMob must be a number`); |
|
|
} |
|
|
|
|
|
const weaponsForShooting = [ |
|
|
"bow", |
|
|
"crossbow", |
|
|
"snowball", |
|
|
"ender_pearl", |
|
|
"egg", |
|
|
"splash_potion", |
|
|
"trident", |
|
|
]; |
|
|
const mainHandItem = bot.inventory.slots[bot.getEquipmentDestSlot("hand")]; |
|
|
|
|
|
const entity = bot.nearestEntity( |
|
|
(entity) => |
|
|
entity.name === mobName && |
|
|
|
|
|
entity.position.distanceTo(bot.entity.position) < 48 |
|
|
); |
|
|
if (!entity) { |
|
|
bot.chat(`No ${mobName} nearby, please explore first`); |
|
|
_killMobFailCount++; |
|
|
if (_killMobFailCount > 10) { |
|
|
throw new Error( |
|
|
`killMob failed too many times, make sure you explore before calling killMob` |
|
|
); |
|
|
} |
|
|
return; |
|
|
} |
|
|
|
|
|
let droppedItem; |
|
|
if (mainHandItem && weaponsForShooting.includes(mainHandItem.name)) { |
|
|
bot.hawkEye.autoAttack(entity, mainHandItem.name); |
|
|
droppedItem = await waitForMobShot(bot, entity, timeout); |
|
|
} else { |
|
|
await bot.pvp.attack(entity); |
|
|
droppedItem = await waitForMobRemoved(bot, entity, timeout); |
|
|
} |
|
|
if (droppedItem) { |
|
|
await bot.collectBlock.collect(droppedItem, { ignoreNoPath: true }); |
|
|
} |
|
|
bot.save(`${mobName}_killed`); |
|
|
} |
|
|
|