diff --git a/src/agent/library/skills.js b/src/agent/library/skills.js index cd9f5b3..ba8c27e 100644 --- a/src/agent/library/skills.js +++ b/src/agent/library/skills.js @@ -10,19 +10,25 @@ export function log(bot, message, chat=false) { bot.chat(message); } +export function shouldPlaceTorch(bot) { + if (!bot.modes.isOn('torch_placing') || bot.interrupt_code) return false; + const pos = world.getPosition(bot); + // TODO: check light level instead of nearby torches, block.light is broken + let nearest_torch = world.getNearestBlock(bot, 'torch', 6); + if (!nearest_torch) { + const block = bot.blockAt(pos); + let has_torch = bot.inventory.items().find(item => item.name === 'torch'); + return has_torch && block.name === 'air'; + } + return false; +} + async function autoLight(bot) { - if (bot.modes.isOn('torch_placing') && !bot.interrupt_code) { - let nearest_torch = world.getNearestBlock(bot, 'torch', 6); - if (!nearest_torch) { - let has_torch = bot.inventory.items().find(item => item.name === 'torch'); - const curr_block = agent.bot.blockAt(pos); - if (has_torch && curr_block.name === 'air') { - try { - log(bot, `Placing torch at ${bot.entity.position}.`); - return await placeBlock(bot, 'torch', bot.entity.position.x, bot.entity.position.y, bot.entity.position.z); - } catch (err) {return true;} - } - } + if (shouldPlaceTorch(bot)) { + try { + const pos = world.getPosition(bot); + return await placeBlock(bot, 'torch', pos.x, pos.y, pos.z, true); + } catch (err) {return false;} } return false; } @@ -455,6 +461,13 @@ export async function breakBlockAt(bot, x, y, z) { if (x == null || y == null || z == null) throw new Error('Invalid position to break block at.'); let block = bot.blockAt(Vec3(x, y, z)); if (block.name !== 'air' && block.name !== 'water' && block.name !== 'lava') { + if (bot.modes.isOn('cheat')) { + let msg = '/setblock ' + Math.floor(x) + ' ' + Math.floor(y) + ' ' + Math.floor(z) + ' air'; + bot.chat(msg); + log(bot, `Used /setblock to break block at ${x}, ${y}, ${z}.`); + return true; + } + if (bot.entity.position.distanceTo(block.position) > 4.5) { let pos = block.position; let movements = new pf.Movements(bot); @@ -482,7 +495,7 @@ export async function breakBlockAt(bot, x, y, z) { } -export async function placeBlock(bot, blockType, x, y, z) { +export async function placeBlock(bot, blockType, x, y, z, no_cheat=false) { /** * Place the given block type at the given position. It will build off from any adjacent blocks. Will fail if there is a block in the way or nothing to build off of. * @param {MinecraftBot} bot, reference to the minecraft bot. @@ -495,7 +508,18 @@ export async function placeBlock(bot, blockType, x, y, z) { * let position = world.getPosition(bot); * await skills.placeBlock(bot, "oak_log", position.x + 1, position.y - 1, position.x); **/ - console.log('placing block...') + if (!mc.getBlockId(blockType)) { + log(bot, `Invalid block type: ${blockType}.`); + return false; + } + + if (bot.modes.isOn('cheat') && !no_cheat) { + let msg = '/setblock ' + Math.floor(x) + ' ' + Math.floor(y) + ' ' + Math.floor(z) + ' ' + blockType; + bot.chat(msg); + log(bot, `Used /setblock to place ${blockType} at ${x}, ${y}, ${z}.`); + return true; + } + let block = bot.inventory.items().find(item => item.name === blockType); if (!block) { log(bot, `Don't have any ${blockType} to place.`); @@ -705,6 +729,13 @@ export async function goToPlayer(bot, username, distance=3) { * @example * await skills.goToPlayer(bot, "player"); **/ + + if (bot.modes.isOn('cheat')) { + bot.chat('/tp @s ' + username); + log(bot, `Teleported to ${username}.`); + return true; + } + bot.modes.pause('self_defense'); bot.modes.pause('cowardice'); let player = bot.players[username].entity @@ -759,6 +790,20 @@ export async function moveAway(bot, distance) { let goal = new pf.goals.GoalNear(pos.x, pos.y, pos.z, distance); let inverted_goal = new pf.goals.GoalInvert(goal); bot.pathfinder.setMovements(new pf.Movements(bot)); + + if (bot.modes.isOn('cheat')) { + const path = await bot.pathfinder.getPathTo(move, inverted_goal, 10000); + let last_move = path.path[path.path.length-1]; + console.log(last_move); + if (last_move) { + let x = Math.floor(last_move.x); + let y = Math.floor(last_move.y); + let z = Math.floor(last_move.z); + bot.chat('/tp @s ' + x + ' ' + y + ' ' + z); + return true; + } + } + await bot.pathfinder.goto(inverted_goal); let new_pos = bot.entity.position; log(bot, `Moved away from nearest entity to ${new_pos}.`); diff --git a/src/agent/modes.js b/src/agent/modes.js index 9a32c0e..4d5b83c 100644 --- a/src/agent/modes.js +++ b/src/agent/modes.js @@ -149,21 +149,16 @@ const modes = [ interrupts: ['followPlayer'], on: true, active: false, + cooldown: 5, + last_place: Date.now(), update: function (agent) { - // TODO: check light level instead of nearby torches, block.light is broken - const near_torch = world.getNearestBlock(agent.bot, 'torch', 6); - if (!near_torch) { - let torches = agent.bot.inventory.items().filter(item => item.name === 'torch'); - if (torches.length > 0) { - const torch = torches[0]; + if (skills.shouldPlaceTorch(agent.bot)) { + if (Date.now() - this.last_place < this.cooldown * 1000) return; + execute(this, agent, async () => { const pos = agent.bot.entity.position; - const curr_block = agent.bot.blockAt(pos); - if (curr_block.name === 'air') { - execute(this, agent, async () => { - await skills.placeBlock(agent.bot, torch.name, pos.x, pos.y, pos.z); - }); - } - } + await skills.placeBlock(agent.bot, 'torch', pos.x, pos.y, pos.z, true); + }); + this.last_place = Date.now(); } } }, @@ -204,6 +199,14 @@ const modes = [ } } }, + { + name: 'cheat', + description: 'Use cheats to instantly place blocks and teleport.', + interrupts: [], + on: false, + active: false, + update: function (agent) { /* do nothing */ } + } ]; async function execute(mode, agent, func, timeout=-1) { @@ -291,4 +294,8 @@ class ModeController { export function initModes(agent) { // the mode controller is added to the bot object so it is accessible from anywhere the bot is used agent.bot.modes = new ModeController(agent); + let modes = agent.prompter.getInitModes(); + if (modes) { + agent.bot.modes.loadJson(modes); + } }