From 58fb27cd66a021e7e0a6694dd208853f93b14b5c Mon Sep 17 00:00:00 2001 From: BF5258 <@gmail.com> Date: Wed, 25 Sep 2024 11:43:31 +1000 Subject: [PATCH 01/10] No longer throws error when quantity of ingredients insufficient. --- src/agent/library/skills.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/agent/library/skills.js b/src/agent/library/skills.js index ec887a2..cffd54b 100644 --- a/src/agent/library/skills.js +++ b/src/agent/library/skills.js @@ -91,8 +91,21 @@ export async function craftRecipe(bot, itemName, num=1) { const recipe = recipes[0]; console.log('crafting...'); - await bot.craft(recipe, num, craftingTable); - log(bot, `Successfully crafted ${itemName}, you now have ${world.getInventoryCounts(bot)[itemName]} ${itemName}.`); + //Check that the agent has sufficient items to use the recipe `num` times. + const inventory = world.getInventoryCounts(bot); + let limitingItem; + let maxNum = num; + for (const ingredient of recipe.ingredients) { + const ingredientName = mc.getItemName(ingredient.id); + const itemsRemaining = inventory[ingredientName] + ingredient.count * maxNum; + if (itemsRemaining < 0) { + limitingItem = ingredientName; + maxNum -= Math.ceil(itemsRemaining / ingredient.count); + } + } + await bot.craft(recipe, maxNum, craftingTable); + if(maxNum Date: Wed, 25 Sep 2024 11:44:21 +1000 Subject: [PATCH 02/10] Crafted armour is equiped --- src/agent/library/skills.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/agent/library/skills.js b/src/agent/library/skills.js index cffd54b..8b1bea8 100644 --- a/src/agent/library/skills.js +++ b/src/agent/library/skills.js @@ -109,6 +109,11 @@ export async function craftRecipe(bot, itemName, num=1) { if (placedTable) { await collectBlock(bot, 'crafting_table', 1); } + + //Equip any armor the bot may have crafted. + //There is probablly a more efficient method than checking the entire inventory but this is all mineflayer-armor-manager provides. :P + bot.armorManager.equipAll(); + return true; } From 778f360ac77b7ecde62072f6d1fc186825283c7a Mon Sep 17 00:00:00 2001 From: BF5258 <@gmail.com> Date: Wed, 25 Sep 2024 12:00:15 +1000 Subject: [PATCH 03/10] See issue #187 --- src/agent/commands/actions.js | 56 +++++----- src/agent/commands/index.js | 193 +++++++++++++++++++++++++++------- src/agent/library/skills.js | 3 - 3 files changed, 182 insertions(+), 70 deletions(-) diff --git a/src/agent/commands/actions.js b/src/agent/commands/actions.js index 651f362..05d2d97 100644 --- a/src/agent/commands/actions.js +++ b/src/agent/commands/actions.js @@ -72,8 +72,8 @@ export const actionsList = [ name: '!goToPlayer', description: 'Go to the given player.', params: { - 'player_name': '(string) The name of the player to go to.', - 'closeness': '(number) How close to get to the player.' + 'player_name': {type: 'string', description: 'The name of the player to go to.'}, + 'closeness': {type: 'float', description: 'How close to get to the player.', 'domain': [0, Infinity]} }, perform: wrapExecution(async (agent, player_name, closeness) => { return await skills.goToPlayer(agent.bot, player_name, closeness); @@ -83,8 +83,8 @@ export const actionsList = [ name: '!followPlayer', description: 'Endlessly follow the given player. Will defend that player if self_defense mode is on.', params: { - 'player_name': '(string) The name of the player to follow.', - 'follow_dist': '(number) The distance to follow from.' + 'player_name': {type: 'string', description: 'name of the player to follow.'}, + 'follow_dist': {type: 'float', description: 'The distance to follow from.', 'domain': [0, Infinity]} }, perform: wrapExecution(async (agent, player_name, follow_dist) => { await skills.followPlayer(agent.bot, player_name, follow_dist); @@ -94,9 +94,9 @@ export const actionsList = [ name: '!goToBlock', description: 'Go to the nearest block of a given type.', params: { - 'type': '(string) The block type to go to.', - 'closeness': '(number) How close to get to the block.', - 'search_range': '(number) The distance to search for the block.' + 'type': { type: 'blockName', description: 'The block type to go to.' }, + 'closeness': { type: 'float', description: 'How close to get to the block.', 'domain': [0, Infinity] }, + 'search_range': { type: 'float', description: 'The distance to search for the block.', 'domain': [0, Infinity] } }, perform: wrapExecution(async (agent, type, closeness, range) => { await skills.goToNearestBlock(agent.bot, type, closeness, range); @@ -105,7 +105,7 @@ export const actionsList = [ { name: '!moveAway', description: 'Move away from the current location in any direction by a given distance.', - params: {'distance': '(number) The distance to move away.'}, + params: {'distance': { type: 'float', description: 'The distance to move away.', 'domain': [0, Infinity] }}, perform: wrapExecution(async (agent, distance) => { await skills.moveAway(agent.bot, distance); }) @@ -113,7 +113,7 @@ export const actionsList = [ { name: '!rememberHere', description: 'Save the current location with a given name.', - params: {'name': '(string) The name to remember the location as.'}, + params: {'name': { type: 'string', description: 'The name to remember the location as.' }}, perform: async function (agent, name) { const pos = agent.bot.entity.position; agent.memory_bank.rememberPlace(name, pos.x, pos.y, pos.z); @@ -123,7 +123,7 @@ export const actionsList = [ { name: '!goToPlace', description: 'Go to a saved location.', - params: {'name': '(string) The name of the location to go to.'}, + params: {'name': { type: 'string', description: 'The name of the location to go to.' }}, perform: wrapExecution(async (agent, name) => { const pos = agent.memory_bank.recallPlace(name); if (!pos) { @@ -137,9 +137,9 @@ export const actionsList = [ name: '!givePlayer', description: 'Give the specified item to the given player.', params: { - 'player_name': '(string) The name of the player to give the item to.', - 'item_name': '(string) The name of the item to give.' , - 'num': '(number) The number of items to give.' + 'player_name': { type: 'string', description: 'The name of the player to give the item to.' }, + 'item_name': { type: 'itemName', description: 'The name of the item to give.' }, + 'num': { type: 'int', description: 'The number of items to give.', 'domain': [1, Number.MAX_SAFE_INTEGER] } }, perform: wrapExecution(async (agent, player_name, item_name, num) => { await skills.giveToPlayer(agent.bot, item_name, player_name, num); @@ -149,8 +149,8 @@ export const actionsList = [ name: '!collectBlocks', description: 'Collect the nearest blocks of a given type.', params: { - 'type': '(string) The block type to collect.', - 'num': '(number) The number of blocks to collect.' + 'type': { type: 'blockName', description: 'The block type to collect.' }, + 'num': { type: 'int', description: 'The number of blocks to collect.', 'domain': [1, Number.MAX_SAFE_INTEGER] } }, perform: wrapExecution(async (agent, type, num) => { await skills.collectBlock(agent.bot, type, num); @@ -160,7 +160,7 @@ export const actionsList = [ name: '!collectAllBlocks', description: 'Collect all the nearest blocks of a given type until told to stop.', params: { - 'type': '(string) The block type to collect.' + 'type': { type: 'blockName', description: 'The block type to collect.' } }, perform: wrapExecution(async (agent, type) => { let success = await skills.collectBlock(agent.bot, type, 1); @@ -172,8 +172,8 @@ export const actionsList = [ name: '!craftRecipe', description: 'Craft the given recipe a given number of times.', params: { - 'recipe_name': '(string) The name of the output item to craft.', - 'num': '(number) The number of times to craft the recipe. This is NOT the number of output items, as it may craft many more items depending on the recipe.' + 'recipe_name': { type: 'itemName', description: 'The name of the output item to craft.' }, + 'num': { type: 'int', description: 'The number of times to craft the recipe. This is NOT the number of output items, as it may craft many more items depending on the recipe.', 'domain': [1, Number.MAX_SAFE_INTEGER] } }, perform: wrapExecution(async (agent, recipe_name, num) => { await skills.craftRecipe(agent.bot, recipe_name, num); @@ -183,8 +183,8 @@ export const actionsList = [ name: '!smeltItem', description: 'Smelt the given item the given number of times.', params: { - 'item_name': '(string) The name of the input item to smelt.', - 'num': '(number) The number of times to smelt the item.' + 'item_name': { type: 'string', description: 'The name of the input item to smelt.' }, + 'num': { type: 'int', description: 'The number of times to smelt the item.', 'domain': [1, Number.MAX_SAFE_INTEGER] } }, perform: async function (agent, item_name, num) { let response = await wrapExecution(async (agent) => { @@ -202,7 +202,7 @@ export const actionsList = [ { name: '!placeHere', description: 'Place a given block in the current location. Do NOT use to build structures, only use for single blocks/torches.', - params: {'type': '(string) The block type to place.'}, + params: {type: 'string', description: 'The block type to place.'}, perform: wrapExecution(async (agent, type) => { let pos = agent.bot.entity.position; await skills.placeBlock(agent.bot, type, pos.x, pos.y, pos.z); @@ -211,7 +211,7 @@ export const actionsList = [ { name: '!attack', description: 'Attack and kill the nearest entity of a given type.', - params: {'type': '(string) The type of entity to attack.'}, + params: {'type': 'string', description: 'The type of entity to attack.'}, perform: wrapExecution(async (agent, type) => { await skills.attackNearest(agent.bot, type, true); }) @@ -226,7 +226,7 @@ export const actionsList = [ { name: '!activate', description: 'Activate the nearest object of a given type.', - params: {'type': '(string) The type of object to activate.'}, + params: {'type': { type: 'blockName', description: 'The type of object to activate.' }}, perform: wrapExecution(async (agent, type) => { await skills.activateNearestBlock(agent.bot, type); }) @@ -242,8 +242,8 @@ export const actionsList = [ name: '!setMode', description: 'Set a mode to on or off. A mode is an automatic behavior that constantly checks and responds to the environment.', params: { - 'mode_name': '(string) The name of the mode to enable.', - 'on': '(bool) Whether to enable or disable the mode.' + 'mode_name': { type: 'string', description: 'The name of the mode to enable.' }, + 'on': { type: 'boolean', description: 'Whether to enable or disable the mode.' } }, perform: async function (agent, mode_name, on) { const modes = agent.bot.modes; @@ -259,7 +259,7 @@ export const actionsList = [ name: '!goal', description: 'Set a goal prompt to endlessly work towards with continuous self-prompting.', params: { - 'selfPrompt': '(string) The goal prompt.', + 'selfPrompt': { type: 'string', description: 'The goal prompt.' }, }, perform: async function (agent, prompt) { agent.self_prompter.start(prompt); // don't await, don't return @@ -277,8 +277,8 @@ export const actionsList = [ name: '!npcGoal', description: 'Set a simple goal for an item or building to automatically work towards. Do not use for complex goals.', params: { - 'name': '(string) The name of the goal to set. Can be item or building name. If empty will automatically choose a goal.', - 'quantity': '(number) The quantity of the goal to set. Default is 1.' + 'name': { type: 'string', description: 'The name of the goal to set. Can be item or building name. If empty will automatically choose a goal.' }, + 'quantity': { type: 'int', description: 'The quantity of the goal to set. Default is 1.', 'domain': [1, Number.MAX_SAFE_INTEGER] } }, perform: async function (agent, name=null, quantity=1) { await agent.npc.setGoal(name, quantity); diff --git a/src/agent/commands/index.js b/src/agent/commands/index.js index 4e3d191..6f5b175 100644 --- a/src/agent/commands/index.js +++ b/src/agent/commands/index.js @@ -1,6 +1,8 @@ +import { getBlockId, getItemId } from "../../utils/mcdata.js"; import { actionsList } from './actions.js'; import { queryList } from './queries.js'; +const suppressNoDomainWarning = false; const commandList = queryList.concat(actionsList); const commandMap = {}; @@ -28,36 +30,131 @@ export function commandExists(commandName) { return commandMap[commandName] !== undefined; } +/** + * Converts a string into a boolean. + * @param {string} input + * @returns {boolean | null} the boolean or `null` if it could not be parsed. + * */ +function parseBoolean(input) { + switch(input.toLowerCase()) { + case 'false': //These are interpreted as flase; + case 'f': + case '0': + case 'off': + return false; + case 'true': //These are interpreted as true; + case 't': + case '1': + case 'on': + return true; + default: + return null; + } +} + +/** + * @param {number} value - the value to check + * @param {number} lowerBound + * @param {number} upperBound + * @param {string} endpointType - The type of the endpoints represented as a two character string. `'[)'` `'()'` + */ +function checkInInterval(number, lowerBound, upperBound, endpointType) { + switch (endpointType) { + case '[)': + return lowerBound <= number && number < upperBound; + case '()': + return lowerBound < number && number < upperBound; + case '(]': + return lowerBound < number && number <= upperBound; + case '[]': + return lowerBound <= number && number <= upperBound; + default: + throw new Error('Unknown endpoint type:', endpointType) + } +} + + + // todo: handle arrays? +/** + * Returns an object containing the command, the command name, and the comand parameters. + * If parsing unsuccessful, returns an error message as a string. + * @param {string} message - A message from a player or language model containing a command. + * @returns {string | Object} + */ function parseCommandMessage(message) { const commandMatch = message.match(commandRegex); - if (commandMatch) { - const commandName = "!"+commandMatch[1]; - if (!commandMatch[2]) - return { commandName, args: [] }; - let args = commandMatch[2].match(argRegex); - if (args) { - for (let i = 0; i < args.length; i++) { - args[i] = args[i].trim(); - } + if (!commandMatch) return `Command is incorrectly formatted`; - for (let i = 0; i < args.length; i++) { - let arg = args[i]; - if ((arg.startsWith('"') && arg.endsWith('"')) || (arg.startsWith("'") && arg.endsWith("'"))) { - args[i] = arg.substring(1, arg.length-1); - } else if (!isNaN(arg)) { - args[i] = Number(arg); - } else if (arg === 'true' || arg === 'false') { - args[i] = arg === 'true'; - } - } + const commandName = "!"+commandMatch[1]; + + let args; + if (commandMatch[2]) args = commandMatch[2].match(argRegex); + else args = []; + + const command = getCommand(commandName); + if(!command) return `${commandName} is not a command.` + + const params = commandParams(command); + const paramNames = commandParamNames(command); + + if (args.length !== params.length) + return `Command ${command.name} was given ${args.length} args, but requires ${params.length} args.`; + + + for (let i = 0; i < args.length; i++) { + const param = params[i]; + //Remove any extra characters + let arg = args[i].trim(); + if ((arg.startsWith('"') && arg.endsWith('"')) || (arg.startsWith("'") && arg.endsWith("'"))) { + arg = arg.substring(1, arg.length-1); } - else - args = []; + //Convert to the correct type + switch(param.type) { + case 'int': + arg = Number.parseInt(arg); break; + case 'float': + arg = Number.parseInt(arg); break; + case 'boolean': + arg = parseBoolean(arg); break; + case 'blockName': + case 'itemName': + if (arg.endsWith('plank')) + arg += 's'; // catches common mistakes like "oak_plank" instead of "oak_planks" + case 'string': + break; + default: + throw new Error(`Command '${commandName}' parameter '${paramNames[i]}' has an unknown type: ${param.type}`); + } + if(arg === null || Number.isNaN(arg)) + return `${paramNames[i]} must be of type ${param.type}.` - return { commandName, args }; + if(typeof arg === 'number') { //Check the domain of numbers + const domain = param.domain; + if(domain) { + /** + * Javascript has a built in object for sets but not intervals. + * Currently the interval (lowerbound,upperbound] is represented as an Array: `[lowerbound, upperbound, '(]']` + */ + if (!domain[2]) domain[2] = '[)'; //By default, lower bound is included. Upper is not. + + if(!checkInInterval(arg, ...domain)) { + return `${paramNames[i]} must be an element of ${domain[2][0]}${domain[0]}, ${domain[1]}${domain[2][1]}.`; // search_range must be an element of [1,64]. + //Alternatively arg could be set to the nearest value in the domain. + } + } else if (!suppressNoDomainWarning) { + console.warn(`Command '${commandName}' parameter '${paramNames[i]}' has no domain set. Expect any value [-Infinity, Infinity].`) + suppressNoDomainWarning = true; //Don't spam console. Only give the warning once. + } + } else if(param.type === 'blockName') { //Check that there is a block with this name + if(getBlockId(arg) == null) return `Invalid block type: ${arg}.` + } else if(param.type === 'itemName') { //Check that there is an item with this name + if(getItemId(arg) == null) return `Invalid item type: ${arg}.` + } + args[i] = arg; } - return null; + + return { commandName, args }; } export function truncCommandMessage(message) { @@ -72,31 +169,49 @@ export function isAction(name) { return actionsList.find(action => action.name === name) !== undefined; } -function numParams(command) { +/** + * @param {Object} command + * @returns {Object[]} The command's parameters. + */ +function commandParams(command) { if (!command.params) - return 0; - return Object.keys(command.params).length; + return []; + return Object.values(command.params); +} + +/** + * @param {Object} command + * @returns {string[]} The names of the command's parameters. + */ +function commandParamNames(command) { + if (!command.params) + return []; + return Object.keys(command.params); +} + +function numParams(command) { + return commandParams(command).length; } export async function executeCommand(agent, message) { let parsed = parseCommandMessage(message); - if (parsed) { - const command = getCommand(parsed.commandName); - let numArgs = 0; - if (parsed.args) { - numArgs = parsed.args.length; - } + if (typeof parsed === 'string') + return parsed; //The command was incorrectly formatted or an invalid input was given. + else { console.log('parsed command:', parsed); - if (numArgs !== numParams(command)) - return `Command ${command.name} was given ${numArgs} args, but requires ${numParams(command)} args.`; - else - return await command.perform(agent, ...parsed.args); + const command = getCommand(parsed.commandName); + return await command.perform(agent, ...parsed.args); } - else - return `Command is incorrectly formatted`; } export function getCommandDocs() { + const typeTranslations = { + 'float': 'number', + 'int': 'number', + 'blockName': 'string', + 'itemName': 'string', + 'boolean': 'bool' + } let docs = `\n*COMMAND DOCS\n You can use the following commands to perform actions and get information about the world. Use the commands with the syntax: !commandName or !commandName("arg1", 1.2, ...) if the command takes arguments.\n Do not use codeblocks. Only use one command in each response, trailing commands and comments will be ignored.\n`; @@ -105,7 +220,7 @@ export function getCommandDocs() { if (command.params) { docs += 'Params:\n'; for (let param in command.params) { - docs += param + ': ' + command.params[param] + '\n'; + docs += `${param}: (${typeTranslations[command.params[param].type]??command.params[param].type}) ${command.params[param].description}\n`; } } } diff --git a/src/agent/library/skills.js b/src/agent/library/skills.js index 8b1bea8..82d4e17 100644 --- a/src/agent/library/skills.js +++ b/src/agent/library/skills.js @@ -44,9 +44,6 @@ export async function craftRecipe(bot, itemName, num=1) { **/ let placedTable = false; - if (itemName.endsWith('plank')) - itemName += 's'; // catches common mistakes like "oak_plank" instead of "oak_planks" - // get recipes that don't require a crafting table let recipes = bot.recipesFor(mc.getItemId(itemName), null, 1, null); let craftingTable = null; From b82af55c4b778c4f568113e24a72b602013849b4 Mon Sep 17 00:00:00 2001 From: BF5258 <@gmail.com> Date: Thu, 26 Sep 2024 16:29:39 +1000 Subject: [PATCH 04/10] Fixed issue #185. Fixed bug I created earlier: crafting shaped recipies works again. --- src/agent/library/skills.js | 74 +++++++++++++++++++++++++++++-------- src/utils/mcdata.js | 5 +++ 2 files changed, 64 insertions(+), 15 deletions(-) diff --git a/src/agent/library/skills.js b/src/agent/library/skills.js index 82d4e17..63a6553 100644 --- a/src/agent/library/skills.js +++ b/src/agent/library/skills.js @@ -32,6 +32,55 @@ async function equipHighestAttack(bot) { await bot.equip(weapon, 'hand'); } +/** + * Returns the number of ingredients required to use the recipe once. + * + * @param {Recipe} recipe + * @returns {Object} an object describing the number of each ingredient. + */ +function ingredientsFromPrismarineRecipe(recipe) { + let requiredIngedients = {}; + if (recipe.inShape) + for (const ingredient of recipe.inShape.flat()) { + if(ingredient.id<0) continue; //prismarine-recipe uses id -1 as an empty crafting slot + const ingredientName = mc.getItemName(ingredient.id); + requiredIngedients[ingredientName] ??=0; + requiredIngedients[ingredientName] += ingredient.count; + } + if (recipe.ingredients) + for (const ingredient of recipe.ingredients) { + if(ingredient.id<0) continue; + const ingredientName = mc.getItemName(ingredient.id); + requiredIngedients[ingredientName] ??=0; + requiredIngedients[ingredientName] -= ingredient.count; + //Yes, the `-=` is intended. + //prismarine-recipe uses positive numbers for the shaped ingredients but negative for unshaped. + //Why this is the case is beyond my understanding. + } + return requiredIngedients; +} + +/** + * Calculates the number of times an action, such as a crafing recipe, can be completed before running out of resources. + * @template T - doesn't have to be an item. This could be any resource. + * @param {Object.} availableItems - The resources available; e.g, `{'cobble_stone': 7, 'stick': 10}` + * @param {Object.} requiredItems - The resources required to complete the action once; e.g, `{'cobble_stone': 3, 'stick': 2}` + * @param {boolean} discrete - Is the action discrete? + * @returns {{num: number, limitingResource: (T | null)}} the number of times the action can be completed and the limmiting resource; e.g `{num: 2, limitingResource: 'cobble_stone'}` + */ +function calculateLimitingResource(availableItems, requiredItems, discrete=true) { + let limitingResource = null; + let num = Infinity; + for (const itemType in requiredItems) { + if (availableItems[itemType] < requiredItems[itemType] * num) { + limitingResource = itemType; + num = availableItems[itemType] / requiredItems[itemType]; + } + } + if(discrete) num = Math.floor(num); + return {num, limitingResource} +} + export async function craftRecipe(bot, itemName, num=1) { /** @@ -48,7 +97,9 @@ export async function craftRecipe(bot, itemName, num=1) { let recipes = bot.recipesFor(mc.getItemId(itemName), null, 1, null); let craftingTable = null; const craftingTableRange = 32; - if (!recipes || recipes.length === 0) { + placeTable: if (!recipes || recipes.length === 0) { + recipes = bot.recipesFor(mc.getItemId(itemName), null, 1, true); + if(!recipes || recipes.length === 0) break placeTable; //Don't bother going to the table if we don't have the required resources. // Look for crafting table craftingTable = world.getNearestBlock(bot, 'crafting_table', craftingTableRange); @@ -66,7 +117,7 @@ export async function craftRecipe(bot, itemName, num=1) { } } else { - log(bot, `You either do not have enough resources to craft ${itemName} or it requires a crafting table.`) + log(bot, `Crafting ${itemName} requires a crafting table.`) return false; } } @@ -89,19 +140,12 @@ export async function craftRecipe(bot, itemName, num=1) { const recipe = recipes[0]; console.log('crafting...'); //Check that the agent has sufficient items to use the recipe `num` times. - const inventory = world.getInventoryCounts(bot); - let limitingItem; - let maxNum = num; - for (const ingredient of recipe.ingredients) { - const ingredientName = mc.getItemName(ingredient.id); - const itemsRemaining = inventory[ingredientName] + ingredient.count * maxNum; - if (itemsRemaining < 0) { - limitingItem = ingredientName; - maxNum -= Math.ceil(itemsRemaining / ingredient.count); - } - } - await bot.craft(recipe, maxNum, craftingTable); - if(maxNum Date: Thu, 26 Sep 2024 16:45:40 +1000 Subject: [PATCH 05/10] 'physicTick' to 'physicsTick' patch --- patches/mineflayer-collectblock+1.4.1.patch | 17 +++++++++++++++-- patches/mineflayer-pvp+1.3.2.patch | 13 +++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 patches/mineflayer-pvp+1.3.2.patch diff --git a/patches/mineflayer-collectblock+1.4.1.patch b/patches/mineflayer-collectblock+1.4.1.patch index cc04fa2..041b577 100644 --- a/patches/mineflayer-collectblock+1.4.1.patch +++ b/patches/mineflayer-collectblock+1.4.1.patch @@ -1,8 +1,8 @@ diff --git a/node_modules/mineflayer-collectblock/lib/CollectBlock.js b/node_modules/mineflayer-collectblock/lib/CollectBlock.js -index 2c11e8c..bc47dc7 100644 +index 2c11e8c..a79a4fb 100644 --- a/node_modules/mineflayer-collectblock/lib/CollectBlock.js +++ b/node_modules/mineflayer-collectblock/lib/CollectBlock.js -@@ -77,7 +77,7 @@ function mineBlock(bot, block, options) { +@@ -77,10 +77,11 @@ function mineBlock(bot, block, options) { } yield bot.tool.equipForBlock(block, equipToolOptions); // @ts-expect-error @@ -11,3 +11,16 @@ index 2c11e8c..bc47dc7 100644 options.targets.removeTarget(block); return; } ++ + const tempEvents = new TemporarySubscriber_1.TemporarySubscriber(bot); + tempEvents.subscribeTo('itemDrop', (entity) => { + if (entity.position.distanceTo(block.position.offset(0.5, 0.5, 0.5)) <= 0.5) { +@@ -92,7 +93,7 @@ function mineBlock(bot, block, options) { + // Waiting for items to drop + yield new Promise(resolve => { + let remainingTicks = 10; +- tempEvents.subscribeTo('physicTick', () => { ++ tempEvents.subscribeTo('physicsTick', () => { + remainingTicks--; + if (remainingTicks <= 0) { + tempEvents.cleanup(); diff --git a/patches/mineflayer-pvp+1.3.2.patch b/patches/mineflayer-pvp+1.3.2.patch new file mode 100644 index 0000000..7ac96b5 --- /dev/null +++ b/patches/mineflayer-pvp+1.3.2.patch @@ -0,0 +1,13 @@ +diff --git a/node_modules/mineflayer-pvp/lib/PVP.js b/node_modules/mineflayer-pvp/lib/PVP.js +index 758c2b3..7c7220e 100644 +--- a/node_modules/mineflayer-pvp/lib/PVP.js ++++ b/node_modules/mineflayer-pvp/lib/PVP.js +@@ -48,7 +48,7 @@ class PVP { + this.meleeAttackRate = new TimingSolver_1.MaxDamageOffset(); + this.bot = bot; + this.movements = new mineflayer_pathfinder_1.Movements(bot, require('minecraft-data')(bot.version)); +- this.bot.on('physicTick', () => this.update()); ++ this.bot.on('physicsTick', () => this.update()); + this.bot.on('entityGone', e => { if (e === this.target) + this.stop(); }); + } From 0bf2e7da0ec6b654a8adab98801f9cbb8624637f Mon Sep 17 00:00:00 2001 From: BF5258 <@gmail.com> Date: Tue, 15 Oct 2024 11:49:12 +1000 Subject: [PATCH 06/10] No punching water. It doesn't work. --- patches/minecraft-data+3.69.0.patch | 198 ++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 patches/minecraft-data+3.69.0.patch diff --git a/patches/minecraft-data+3.69.0.patch b/patches/minecraft-data+3.69.0.patch new file mode 100644 index 0000000..4463fb5 --- /dev/null +++ b/patches/minecraft-data+3.69.0.patch @@ -0,0 +1,198 @@ +diff --git a/node_modules/minecraft-data/minecraft-data/data/pc/1.19.2/blocks.json b/node_modules/minecraft-data/minecraft-data/data/pc/1.19.2/blocks.json +index 26c376e..754e48a 100644 +--- a/node_modules/minecraft-data/minecraft-data/data/pc/1.19.2/blocks.json ++++ b/node_modules/minecraft-data/minecraft-data/data/pc/1.19.2/blocks.json +@@ -756,7 +756,7 @@ + "hardness": 100.0, + "resistance": 100.0, + "stackSize": 64, +- "diggable": true, ++ "diggable": false, + "material": "default", + "transparent": true, + "emitLight": 0, +@@ -799,7 +799,7 @@ + "hardness": 100.0, + "resistance": 100.0, + "stackSize": 64, +- "diggable": true, ++ "diggable": false, + "material": "default", + "transparent": true, + "emitLight": 15, +diff --git a/node_modules/minecraft-data/minecraft-data/data/pc/1.19.3/blocks.json b/node_modules/minecraft-data/minecraft-data/data/pc/1.19.3/blocks.json +index 2086596..3712912 100644 +--- a/node_modules/minecraft-data/minecraft-data/data/pc/1.19.3/blocks.json ++++ b/node_modules/minecraft-data/minecraft-data/data/pc/1.19.3/blocks.json +@@ -794,7 +794,7 @@ + "hardness": 100.0, + "resistance": 100.0, + "stackSize": 64, +- "diggable": true, ++ "diggable": false, + "material": "default", + "transparent": true, + "emitLight": 0, +@@ -837,7 +837,7 @@ + "hardness": 100.0, + "resistance": 100.0, + "stackSize": 64, +- "diggable": true, ++ "diggable": false, + "material": "default", + "transparent": true, + "emitLight": 15, +diff --git a/node_modules/minecraft-data/minecraft-data/data/pc/1.19.4/blocks.json b/node_modules/minecraft-data/minecraft-data/data/pc/1.19.4/blocks.json +index 25378bd..c137b84 100644 +--- a/node_modules/minecraft-data/minecraft-data/data/pc/1.19.4/blocks.json ++++ b/node_modules/minecraft-data/minecraft-data/data/pc/1.19.4/blocks.json +@@ -842,7 +842,7 @@ + "hardness": 100.0, + "resistance": 100.0, + "stackSize": 64, +- "diggable": true, ++ "diggable": false, + "material": "default", + "transparent": true, + "emitLight": 0, +@@ -885,7 +885,7 @@ + "hardness": 100.0, + "resistance": 100.0, + "stackSize": 64, +- "diggable": true, ++ "diggable": false, + "material": "default", + "transparent": true, + "emitLight": 15, +diff --git a/node_modules/minecraft-data/minecraft-data/data/pc/1.19/blocks.json b/node_modules/minecraft-data/minecraft-data/data/pc/1.19/blocks.json +index b5fc758..4a0f18f 100644 +--- a/node_modules/minecraft-data/minecraft-data/data/pc/1.19/blocks.json ++++ b/node_modules/minecraft-data/minecraft-data/data/pc/1.19/blocks.json +@@ -756,7 +756,7 @@ + "hardness": 100.0, + "resistance": 100.0, + "stackSize": 64, +- "diggable": true, ++ "diggable": false, + "material": "default", + "transparent": true, + "emitLight": 0, +@@ -799,7 +799,7 @@ + "hardness": 100.0, + "resistance": 100.0, + "stackSize": 64, +- "diggable": true, ++ "diggable": false, + "material": "default", + "transparent": true, + "emitLight": 15, +diff --git a/node_modules/minecraft-data/minecraft-data/data/pc/1.20.2/blocks.json b/node_modules/minecraft-data/minecraft-data/data/pc/1.20.2/blocks.json +index 053351c..d2544b9 100644 +--- a/node_modules/minecraft-data/minecraft-data/data/pc/1.20.2/blocks.json ++++ b/node_modules/minecraft-data/minecraft-data/data/pc/1.20.2/blocks.json +@@ -850,7 +850,7 @@ + "hardness": 100.0, + "resistance": 100.0, + "stackSize": 64, +- "diggable": true, ++ "diggable": false, + "material": "default", + "transparent": true, + "emitLight": 0, +@@ -893,7 +893,7 @@ + "hardness": 100.0, + "resistance": 100.0, + "stackSize": 64, +- "diggable": true, ++ "diggable": false, + "material": "default", + "transparent": true, + "emitLight": 15, +diff --git a/node_modules/minecraft-data/minecraft-data/data/pc/1.20.3/blocks.json b/node_modules/minecraft-data/minecraft-data/data/pc/1.20.3/blocks.json +index a11ac9e..cfa1c5c 100644 +--- a/node_modules/minecraft-data/minecraft-data/data/pc/1.20.3/blocks.json ++++ b/node_modules/minecraft-data/minecraft-data/data/pc/1.20.3/blocks.json +@@ -850,7 +850,7 @@ + "hardness": 100.0, + "resistance": 100.0, + "stackSize": 64, +- "diggable": true, ++ "diggable": false, + "material": "default", + "transparent": true, + "emitLight": 0, +@@ -893,7 +893,7 @@ + "hardness": 100.0, + "resistance": 100.0, + "stackSize": 64, +- "diggable": true, ++ "diggable": false, + "material": "default", + "transparent": true, + "emitLight": 15, +diff --git a/node_modules/minecraft-data/minecraft-data/data/pc/1.20.4/blocks.json b/node_modules/minecraft-data/minecraft-data/data/pc/1.20.4/blocks.json +index 3e555dd..3638aa6 100644 +--- a/node_modules/minecraft-data/minecraft-data/data/pc/1.20.4/blocks.json ++++ b/node_modules/minecraft-data/minecraft-data/data/pc/1.20.4/blocks.json +@@ -850,7 +850,7 @@ + "hardness": 100.0, + "resistance": 100.0, + "stackSize": 64, +- "diggable": true, ++ "diggable": false, + "material": "default", + "transparent": true, + "emitLight": 0, +@@ -893,7 +893,7 @@ + "hardness": 100.0, + "resistance": 100.0, + "stackSize": 64, +- "diggable": true, ++ "diggable": false, + "material": "default", + "transparent": true, + "emitLight": 15, +diff --git a/node_modules/minecraft-data/minecraft-data/data/pc/1.20.5/blocks.json b/node_modules/minecraft-data/minecraft-data/data/pc/1.20.5/blocks.json +index 2763f38..54fa499 100644 +--- a/node_modules/minecraft-data/minecraft-data/data/pc/1.20.5/blocks.json ++++ b/node_modules/minecraft-data/minecraft-data/data/pc/1.20.5/blocks.json +@@ -850,7 +850,7 @@ + "hardness": 100.0, + "resistance": 100.0, + "stackSize": 64, +- "diggable": true, ++ "diggable": false, + "material": "default", + "transparent": true, + "emitLight": 0, +@@ -893,7 +893,7 @@ + "hardness": 100.0, + "resistance": 100.0, + "stackSize": 64, +- "diggable": true, ++ "diggable": false, + "material": "default", + "transparent": true, + "emitLight": 15, +diff --git a/node_modules/minecraft-data/minecraft-data/data/pc/1.20/blocks.json b/node_modules/minecraft-data/minecraft-data/data/pc/1.20/blocks.json +index f265dc1..e8eb68f 100644 +--- a/node_modules/minecraft-data/minecraft-data/data/pc/1.20/blocks.json ++++ b/node_modules/minecraft-data/minecraft-data/data/pc/1.20/blocks.json +@@ -850,7 +850,7 @@ + "hardness": 100.0, + "resistance": 100.0, + "stackSize": 64, +- "diggable": true, ++ "diggable": false, + "material": "default", + "transparent": true, + "emitLight": 0, +@@ -893,7 +893,7 @@ + "hardness": 100.0, + "resistance": 100.0, + "stackSize": 64, +- "diggable": true, ++ "diggable": false, + "material": "default", + "transparent": true, + "emitLight": 15, From cc6fc66be289498b7ba525b049269a32bb5fbfd5 Mon Sep 17 00:00:00 2001 From: MaxRobinsonTheGreat Date: Tue, 15 Oct 2024 17:03:51 -0500 Subject: [PATCH 07/10] fixed a couple bugs --- src/agent/commands/index.js | 8 ++++---- src/utils/mcdata.js | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/agent/commands/index.js b/src/agent/commands/index.js index 1529dbe..cc2c847 100644 --- a/src/agent/commands/index.js +++ b/src/agent/commands/index.js @@ -2,7 +2,7 @@ import { getBlockId, getItemId } from "../../utils/mcdata.js"; import { actionsList } from './actions.js'; import { queryList } from './queries.js'; -const suppressNoDomainWarning = false; +let suppressNoDomainWarning = false; const commandList = queryList.concat(actionsList); const commandMap = {}; @@ -114,7 +114,7 @@ function parseCommandMessage(message) { case 'int': arg = Number.parseInt(arg); break; case 'float': - arg = Number.parseInt(arg); break; + arg = Number.parseFloat(arg); break; case 'boolean': arg = parseBoolean(arg); break; case 'BlockName': @@ -127,7 +127,7 @@ function parseCommandMessage(message) { throw new Error(`Command '${commandName}' parameter '${paramNames[i]}' has an unknown type: ${param.type}`); } if(arg === null || Number.isNaN(arg)) - return `${paramNames[i]} must be of type ${param.type}.` + return `Error: Param '${paramNames[i]}' must be of type ${param.type}.` if(typeof arg === 'number') { //Check the domain of numbers const domain = param.domain; @@ -139,7 +139,7 @@ function parseCommandMessage(message) { if (!domain[2]) domain[2] = '[)'; //By default, lower bound is included. Upper is not. if(!checkInInterval(arg, ...domain)) { - return `${paramNames[i]} must be an element of ${domain[2][0]}${domain[0]}, ${domain[1]}${domain[2][1]}.`; // search_range must be an element of [1,64]. + return `Error: Param '${paramNames[i]}' must be an element of ${domain[2][0]}${domain[0]}, ${domain[1]}${domain[2][1]}.`; //Alternatively arg could be set to the nearest value in the domain. } } else if (!suppressNoDomainWarning) { diff --git a/src/utils/mcdata.js b/src/utils/mcdata.js index 429719c..377b1c7 100644 --- a/src/utils/mcdata.js +++ b/src/utils/mcdata.js @@ -259,14 +259,14 @@ export function ingredientsFromPrismarineRecipe(recipe) { if (recipe.inShape) for (const ingredient of recipe.inShape.flat()) { if(ingredient.id<0) continue; //prismarine-recipe uses id -1 as an empty crafting slot - const ingredientName = mc.getItemName(ingredient.id); + const ingredientName = getItemName(ingredient.id); requiredIngedients[ingredientName] ??=0; requiredIngedients[ingredientName] += ingredient.count; } if (recipe.ingredients) for (const ingredient of recipe.ingredients) { if(ingredient.id<0) continue; - const ingredientName = mc.getItemName(ingredient.id); + const ingredientName = getItemName(ingredient.id); requiredIngedients[ingredientName] ??=0; requiredIngedients[ingredientName] -= ingredient.count; //Yes, the `-=` is intended. From ce5faa94aa26a2ff88e0f2246fd0735d9973f7a2 Mon Sep 17 00:00:00 2001 From: MaxRobinsonTheGreat Date: Tue, 15 Oct 2024 17:04:19 -0500 Subject: [PATCH 08/10] handle equipped armor fo inventory --- src/agent/commands/queries.js | 17 +++++++++++++++++ src/agent/library/skills.js | 5 +++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/agent/commands/queries.js b/src/agent/commands/queries.js index 322efb5..05938bc 100644 --- a/src/agent/commands/queries.js +++ b/src/agent/commands/queries.js @@ -66,6 +66,23 @@ export const queryList = [ else if (agent.bot.game.gameMode === 'creative') { res += '\n(You have infinite items in creative mode. You do not need to gather resources!!)'; } + + let helmet = bot.inventory.slots[5]; + let chestplate = bot.inventory.slots[6]; + let leggings = bot.inventory.slots[7]; + let boots = bot.inventory.slots[8]; + res += '\nWEARING: '; + if (helmet) + res += `\nHead: ${helmet.name}`; + if (chestplate) + res += `\nTorso: ${chestplate.name}`; + if (leggings) + res += `\nLegs: ${leggings.name}`; + if (boots) + res += `\nFeet: ${boots.name}`; + if (!helmet && !chestplate && !leggings && !boots) + res += 'None'; + return pad(res); } }, diff --git a/src/agent/library/skills.js b/src/agent/library/skills.js index d9816fb..5aa20a8 100644 --- a/src/agent/library/skills.js +++ b/src/agent/library/skills.js @@ -673,7 +673,7 @@ export async function equip(bot, itemName) { * @example * await skills.equip(bot, "iron_pickaxe"); **/ - let item = bot.inventory.items().find(item => item.name === itemName); + let item = bot.inventory.slots.find(slot => slot && slot.name === itemName); if (!item) { log(bot, `You do not have any ${itemName} to equip.`); return false; @@ -687,12 +687,13 @@ export async function equip(bot, itemName) { else if (itemName.includes('helmet')) { await bot.equip(item, 'head'); } - else if (itemName.includes('chestplate')) { + else if (itemName.includes('chestplate') || itemName.includes('elytra')) { await bot.equip(item, 'torso'); } else { await bot.equip(item, 'hand'); } + log(bot, `Equipped ${itemName}.`); return true; } From 90d72a006969f22cc419d57efe771729310a120d Mon Sep 17 00:00:00 2001 From: MaxRobinsonTheGreat Date: Tue, 15 Oct 2024 17:05:30 -0500 Subject: [PATCH 09/10] removed blocks patch --- patches/minecraft-data+3.69.0.patch | 198 ---------------------------- 1 file changed, 198 deletions(-) delete mode 100644 patches/minecraft-data+3.69.0.patch diff --git a/patches/minecraft-data+3.69.0.patch b/patches/minecraft-data+3.69.0.patch deleted file mode 100644 index 4463fb5..0000000 --- a/patches/minecraft-data+3.69.0.patch +++ /dev/null @@ -1,198 +0,0 @@ -diff --git a/node_modules/minecraft-data/minecraft-data/data/pc/1.19.2/blocks.json b/node_modules/minecraft-data/minecraft-data/data/pc/1.19.2/blocks.json -index 26c376e..754e48a 100644 ---- a/node_modules/minecraft-data/minecraft-data/data/pc/1.19.2/blocks.json -+++ b/node_modules/minecraft-data/minecraft-data/data/pc/1.19.2/blocks.json -@@ -756,7 +756,7 @@ - "hardness": 100.0, - "resistance": 100.0, - "stackSize": 64, -- "diggable": true, -+ "diggable": false, - "material": "default", - "transparent": true, - "emitLight": 0, -@@ -799,7 +799,7 @@ - "hardness": 100.0, - "resistance": 100.0, - "stackSize": 64, -- "diggable": true, -+ "diggable": false, - "material": "default", - "transparent": true, - "emitLight": 15, -diff --git a/node_modules/minecraft-data/minecraft-data/data/pc/1.19.3/blocks.json b/node_modules/minecraft-data/minecraft-data/data/pc/1.19.3/blocks.json -index 2086596..3712912 100644 ---- a/node_modules/minecraft-data/minecraft-data/data/pc/1.19.3/blocks.json -+++ b/node_modules/minecraft-data/minecraft-data/data/pc/1.19.3/blocks.json -@@ -794,7 +794,7 @@ - "hardness": 100.0, - "resistance": 100.0, - "stackSize": 64, -- "diggable": true, -+ "diggable": false, - "material": "default", - "transparent": true, - "emitLight": 0, -@@ -837,7 +837,7 @@ - "hardness": 100.0, - "resistance": 100.0, - "stackSize": 64, -- "diggable": true, -+ "diggable": false, - "material": "default", - "transparent": true, - "emitLight": 15, -diff --git a/node_modules/minecraft-data/minecraft-data/data/pc/1.19.4/blocks.json b/node_modules/minecraft-data/minecraft-data/data/pc/1.19.4/blocks.json -index 25378bd..c137b84 100644 ---- a/node_modules/minecraft-data/minecraft-data/data/pc/1.19.4/blocks.json -+++ b/node_modules/minecraft-data/minecraft-data/data/pc/1.19.4/blocks.json -@@ -842,7 +842,7 @@ - "hardness": 100.0, - "resistance": 100.0, - "stackSize": 64, -- "diggable": true, -+ "diggable": false, - "material": "default", - "transparent": true, - "emitLight": 0, -@@ -885,7 +885,7 @@ - "hardness": 100.0, - "resistance": 100.0, - "stackSize": 64, -- "diggable": true, -+ "diggable": false, - "material": "default", - "transparent": true, - "emitLight": 15, -diff --git a/node_modules/minecraft-data/minecraft-data/data/pc/1.19/blocks.json b/node_modules/minecraft-data/minecraft-data/data/pc/1.19/blocks.json -index b5fc758..4a0f18f 100644 ---- a/node_modules/minecraft-data/minecraft-data/data/pc/1.19/blocks.json -+++ b/node_modules/minecraft-data/minecraft-data/data/pc/1.19/blocks.json -@@ -756,7 +756,7 @@ - "hardness": 100.0, - "resistance": 100.0, - "stackSize": 64, -- "diggable": true, -+ "diggable": false, - "material": "default", - "transparent": true, - "emitLight": 0, -@@ -799,7 +799,7 @@ - "hardness": 100.0, - "resistance": 100.0, - "stackSize": 64, -- "diggable": true, -+ "diggable": false, - "material": "default", - "transparent": true, - "emitLight": 15, -diff --git a/node_modules/minecraft-data/minecraft-data/data/pc/1.20.2/blocks.json b/node_modules/minecraft-data/minecraft-data/data/pc/1.20.2/blocks.json -index 053351c..d2544b9 100644 ---- a/node_modules/minecraft-data/minecraft-data/data/pc/1.20.2/blocks.json -+++ b/node_modules/minecraft-data/minecraft-data/data/pc/1.20.2/blocks.json -@@ -850,7 +850,7 @@ - "hardness": 100.0, - "resistance": 100.0, - "stackSize": 64, -- "diggable": true, -+ "diggable": false, - "material": "default", - "transparent": true, - "emitLight": 0, -@@ -893,7 +893,7 @@ - "hardness": 100.0, - "resistance": 100.0, - "stackSize": 64, -- "diggable": true, -+ "diggable": false, - "material": "default", - "transparent": true, - "emitLight": 15, -diff --git a/node_modules/minecraft-data/minecraft-data/data/pc/1.20.3/blocks.json b/node_modules/minecraft-data/minecraft-data/data/pc/1.20.3/blocks.json -index a11ac9e..cfa1c5c 100644 ---- a/node_modules/minecraft-data/minecraft-data/data/pc/1.20.3/blocks.json -+++ b/node_modules/minecraft-data/minecraft-data/data/pc/1.20.3/blocks.json -@@ -850,7 +850,7 @@ - "hardness": 100.0, - "resistance": 100.0, - "stackSize": 64, -- "diggable": true, -+ "diggable": false, - "material": "default", - "transparent": true, - "emitLight": 0, -@@ -893,7 +893,7 @@ - "hardness": 100.0, - "resistance": 100.0, - "stackSize": 64, -- "diggable": true, -+ "diggable": false, - "material": "default", - "transparent": true, - "emitLight": 15, -diff --git a/node_modules/minecraft-data/minecraft-data/data/pc/1.20.4/blocks.json b/node_modules/minecraft-data/minecraft-data/data/pc/1.20.4/blocks.json -index 3e555dd..3638aa6 100644 ---- a/node_modules/minecraft-data/minecraft-data/data/pc/1.20.4/blocks.json -+++ b/node_modules/minecraft-data/minecraft-data/data/pc/1.20.4/blocks.json -@@ -850,7 +850,7 @@ - "hardness": 100.0, - "resistance": 100.0, - "stackSize": 64, -- "diggable": true, -+ "diggable": false, - "material": "default", - "transparent": true, - "emitLight": 0, -@@ -893,7 +893,7 @@ - "hardness": 100.0, - "resistance": 100.0, - "stackSize": 64, -- "diggable": true, -+ "diggable": false, - "material": "default", - "transparent": true, - "emitLight": 15, -diff --git a/node_modules/minecraft-data/minecraft-data/data/pc/1.20.5/blocks.json b/node_modules/minecraft-data/minecraft-data/data/pc/1.20.5/blocks.json -index 2763f38..54fa499 100644 ---- a/node_modules/minecraft-data/minecraft-data/data/pc/1.20.5/blocks.json -+++ b/node_modules/minecraft-data/minecraft-data/data/pc/1.20.5/blocks.json -@@ -850,7 +850,7 @@ - "hardness": 100.0, - "resistance": 100.0, - "stackSize": 64, -- "diggable": true, -+ "diggable": false, - "material": "default", - "transparent": true, - "emitLight": 0, -@@ -893,7 +893,7 @@ - "hardness": 100.0, - "resistance": 100.0, - "stackSize": 64, -- "diggable": true, -+ "diggable": false, - "material": "default", - "transparent": true, - "emitLight": 15, -diff --git a/node_modules/minecraft-data/minecraft-data/data/pc/1.20/blocks.json b/node_modules/minecraft-data/minecraft-data/data/pc/1.20/blocks.json -index f265dc1..e8eb68f 100644 ---- a/node_modules/minecraft-data/minecraft-data/data/pc/1.20/blocks.json -+++ b/node_modules/minecraft-data/minecraft-data/data/pc/1.20/blocks.json -@@ -850,7 +850,7 @@ - "hardness": 100.0, - "resistance": 100.0, - "stackSize": 64, -- "diggable": true, -+ "diggable": false, - "material": "default", - "transparent": true, - "emitLight": 0, -@@ -893,7 +893,7 @@ - "hardness": 100.0, - "resistance": 100.0, - "stackSize": 64, -- "diggable": true, -+ "diggable": false, - "material": "default", - "transparent": true, - "emitLight": 15, From 9d09db7b76df69c44be810823727f74aa3439d61 Mon Sep 17 00:00:00 2001 From: MaxRobinsonTheGreat Date: Wed, 16 Oct 2024 00:02:59 -0500 Subject: [PATCH 10/10] corrected newaction param --- src/agent/commands/actions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/agent/commands/actions.js b/src/agent/commands/actions.js index cea4c25..0e87c78 100644 --- a/src/agent/commands/actions.js +++ b/src/agent/commands/actions.js @@ -23,7 +23,7 @@ export const actionsList = [ name: '!newAction', description: 'Perform new and unknown custom behaviors that are not available as a command.', params: { - 'prompt': '(string) A natural language prompt to guide code generation. Make a detailed step-by-step plan.' + 'prompt': { type: 'string', description: 'A natural language prompt to guide code generation. Make a detailed step-by-step plan.' } }, perform: async function (agent, prompt) { // just ignore prompt - it is now in context in chat history