PrismarineJS / mineflayer

Create Minecraft bots with a powerful, stable, and high level JavaScript API.
https://prismarinejs.github.io/mineflayer/
MIT License
4.95k stars 904 forks source link

(1.18.2) Bot cannot climb specific stair when going up #3033

Closed SonicandTailsCD closed 1 year ago

SonicandTailsCD commented 1 year ago

Versions

Detailed description of a problem

A clear and concise description of what the problem is, with as much context as possible. Previously, the bot would climb all the stairs without any problem. Now, it can't go with me and it tries to break the stairs. Doesn't help much as the bot can't come to me either. What are you building? Bot companion :) What problem are you trying to solve? I need it to stop breaking the stairs

What did you try yet?

Did you try any method from the API? What's an API? Did you try any example? No, it's not necessary.

Your current code


// this is bot.ts
// Here I tell node.js mineflayer and a few other plugins are required to load
import { createBot } from 'mineflayer';
import pathfinderPkg from 'mineflayer-pathfinder';
import { botStates, commands, setup as setupCmds } from './lib/commands.js';
import { setup as setupMfUtils } from './lib/mineflayer-utils.js';
const { pathfinder, Movements } = pathfinderPkg;

// Here, we set up the server connection (in this case, my skin plugin server)
console.log('Registering the bot and allowing node to control it...')
export const bot = createBot({
    host: 'SonicJavaBots.aternos.me',
    port: 37867,
    username: 'SonicandTailsCDb',
    version: '1.18.2'
});
console.log('Bot client initialized!');
console.log('Node.JS can control the bot now.')
console.log('Setting up MfUtils and Cmds')
setupMfUtils(bot);
setupCmds(bot);
console.log('Done :)')

// Setup pathfinder
console.log('Setting up pathfinder...')
bot.loadPlugin(pathfinder);
const movements = new Movements(bot, bot.registry);
bot.pathfinder.setMovements(movements);
bot.pathfinder.thinkTimeout = 10000;
bot.pathfinder.tickTimeout = 22
console.log('Done :)')

// And now, we work on the AI here!
// Here's all of the functions:
// One note tho: All functions are placeholders.
// function onPhysicsTick (): void {}

console.log('Registering function...')
function onSpawn (): void {
    bot.chat('/skin set SonicandTailsCDb robot1_alextest');
    console.log('Bot initialized completely :)');
    bot.chat("Hey! I'm working properly :D");

    bot.on('chat', async (daname, msg) => {
        if (daname === 'SkinsRestorer') return;
        console.log(daname + ' said: ' + msg);
        if (msg === 'follow me') {
            while (commands.followMe(daname)) {
                console.log('I started following ' + daname);
                return;
            }
        }
        if (msg === 'hello') {
            bot.chat('Hi! :)')
        }
        if (msg === 'Reset your viewing location') {
            await bot.chat('Sure, I\'ll do that :)')
            await bot.waitForTicks(10)
            commands.resetViewingLocation()
        }
        if (msg === 'Where are you, bot?') {
            console.log('Bot is giving its location to ' + daname + '!')
            commands.location(daname)
        }
        if (msg === 'Sleep with me :)') {
            await commands.sleep();
        }
        if (msg === 'eat with me') {
            commands.eatWithPlayer(daname)
        }
        if (msg === 'CLEEANN!') {
            await commands.mineAround();
        }
        if (msg === 'Stop cleaning') {
            await commands.stopMining();
        }
        if (msg === 'Protect me :)') {
            try {
                commands.protectMe(daname)
            }
            catch (err) {
                console.log(String(err?.message))
            }
            console.log('Bot instructed to protect ' + daname + ', obeying player...')
        }
        if (msg === 'attack me') {
            const message = "Alright, run while you still can!"
            bot.chat(message)
            commands.attackPlayer(daname)
        }
        if (msg === 'Stop attacking me') {
            commands.stopAttacking()
        }
        if (msg === 'attack any entity') {
            commands.attackEntity()
        }
        if (msg === 'Stop server') {
            bot.chat('Okay!')
            await bot.waitForTicks(60)
            bot.chat('/stop')
        }
        if (msg === 'hey') {
            bot.chat('what you want?');
            console.log('I said: what you want?');
        }
        if (msg === 'Say hi to 678435021') {
            bot.chat("Oh, I'm sorry! Hi 678435021! :)")
        }
        if (msg === 'stop following me') {
            commands.unFollowMe();
            console.log('I stopped following ' + daname);
        }
    });
}
console.log('Done :)')
// I'm unsure on how am I gonna use onPhysicsTick function but I'll leave it there in case me or @678435021 wanna use it.
// bot.on('physicsTick', onPhysicsTick);

// Next, I'm gonna set spawn actions.
console.log('Running now!')
bot.once('spawn', onSpawn);

// now commands.ts
import { lookAtEntity } from './mineflayer-utils.js';
import { sleep } from './sleep.js';
import pathfinderPkg from 'mineflayer-pathfinder';
import { Bot } from 'mineflayer';
const { goals } = pathfinderPkg;

let bot: Bot;
export function setup (_bot: Bot): void {
    bot = _bot;
}
let target: any = null;
let player = null;
export const protectUser = null;
// 678435021: Add more here when needed
// SonicandTailsCD: Alright, I will :P
export const botStates = {
    moving: false,
    looking: false,
    mining: false,
    following: false,
    mentionedEatingWithPlayerAlready: false,
    attacking: false,
    guarding: false
};

// Add here any values when needed.
export const values = {
    range: 3,
    BlocksAwayFromTarget: 3,
    entities: []
};

export const commands = {
    async sleep () {
        try {
            console.log('Sleeping!');
            bot.chat("I'm coming :D");
            const bed = bot.findBlock({ matching: block => bot.isABed(block) });
            if (!bed) {
                console.log("Sorry, I can't find a bed!");
                return;
            }
            await bot.sleep(bed);
        }
        catch(err) {
            bot.chat('Sorry, I couldn\'t sleep! Please check the console log.');
            console.log(String(err?.message));
        }
    },
    async location (daname: string) {
        bot.chat(daname + ", I\'m at " + bot.entity.position)
    },
    async stopMining () {
        bot.chat('Okay! I\'ll stop.');
        botStates.mining = false;
    },
    async attackPlayer (daname: string) {
        const player = bot.players[daname]
        if (!player || !player.entity) {
            bot.chat('I can\'t see you')
        } 
        else {
            bot.chat(`Attacking ${player.username}`)
            botStates.attacking = true
            while (botStates.attacking = true) {
                await bot.waitForTicks(5)
                bot.attack(player.entity)
            }
        }
    },
    async stopAttacking () {
        botStates.attacking = false
        bot.chat('Okay, I won\'t attack you anymore.')
    },
    async attackEntity () {
        const entity = bot.nearestEntity()
        if (!entity) {
          bot.chat('No nearby entities')
        } else {
          bot.chat('Attacking ${entity.name ?? entity.username}')
          bot.attack(entity)
        }
    },
    async eatWithPlayer(daname: string) {
        this.followMe(daname)
        if (botStates.mentionedEatingWithPlayerAlready = true) {
            console.log('Already mentioned coming to player!')
        } 
        else {
            bot.chat('Let me come to you first! :D')
            botStates.mentionedEatingWithPlayerAlready = true
        }
        if (botStates.looking = true) {
            const eatitem: any = bot.inventory.items().find(item => item.name === 'Suspicious Stew')
            const eatTime = 1500
            try {
                await bot.equip(eatitem, 'hand')
                bot.chat("Sorry, I'm still being worked on. I cannot eat yet.")
            }
            catch (err) {
                bot.chat(String(err?.message))
            }
            bot.activateItem()
            await sleep(eatTime)
            bot.deactivateItem()
            botStates.mentionedEatingWithPlayerAlready = false;

        }
        else {
            bot.waitForTicks(200)
            botStates.mentionedEatingWithPlayerAlready = true
            this.eatWithPlayer(daname)
        }
    },
    async mineAround () {
        if (botStates.mining) {
            return;
        }

        bot.chat('Anything for you! :)');

        botStates.mining = true;
        while (botStates.mining) {
            await bot.waitForTicks(1);
            const grassBlock = bot.findBlock({
                matching: block => {
                    return block.name === 'grass' || block.name === 'tall_grass';
                }
            });

            if (!grassBlock) {
                console.log("Couldn't find grass.");
                await sleep(100);
                continue;
            }

            try {
                await bot.pathfinder.goto(
                    new goals.GoalLookAtBlock(
                        grassBlock.position, bot.world, {
                            reach: 2.5,
                            entityHeight: bot.player.entity.height
                        }
                    )
                );
            } 
            catch (e) {
                continue;
            }

            await bot.dig(grassBlock, true);
        }
    },
    async speakProtect () {
        bot.chat('Coming now :D')
    },
    async resetViewingLocation () {
        await bot.lookAt(45, 0);
        await bot.lookAt(0, 0);
    },
    async protectMe (daname: string) {
        botStates.guarding = true
        if (botStates.following = true) {
            console.log('Already following a player, skipping follow activation!')
            if (player =! daname) {
                bot.chat('You\'re not the one I\'m following! I\'m not obeying you. >:(')
                return
            }
            const protectUser = daname;
            this.speakProtect()
        }
        else {
            console.log('Since the bot isn\'t following anything, the bot will begin following ' + daname)
            this.followMe(daname)
            this.speakProtect()
            const player = bot.players[daname];
            const protectUser = player
        }
        bot.on('entityHurt', async (entity)=>{
            target = entity
            try {
                if (botStates.attacking = true) return
                if (target.username != protectUser) return
                botStates.attacking = true
                await bot.setControlState('forward', true)
                await bot.setControlState('sprint', true)
                const location = target.position
                botStates.guarding = false
                while (botStates.attacking = true) {
                    botStates.following = false
                    await bot.waitForTicks(5)
                    let distance = bot.entity.position.xzDistanceTo(location)
                    while (distance = values.BlocksAwayFromTarget) {
                        await bot.attack(target)
                        bot.lookAt(location)
                    }
                }
            }
            catch (err) {
                console.log('The bot wasn\'t able to help ' + protectUser + ' fight! :(')
            }
        })
        bot.on('entityGone', async (entity)=>{
            if (entity = target) {
                botStates.attacking = false
                botStates.guarding = true
                botStates.following = true
            }
            else return
        })
    },
    async followMe (daname: string) {
        botStates.following = true;

        const player = bot.players[daname];
        if (botStates.moving) {
            bot.chat("Sorry, can't run this command more than once!");
        }
        botStates.moving = true;

        if (!player?.entity) {
            bot.chat("I can't see you, " + daname);
            botStates.moving = false;
            return;
        }

        bot.chat('Okay ' + daname);

        while (botStates.following) {
            try {
                if (bot.entity.position.distanceTo(player.entity.position) + 0.15 <= values.range) {
                    await lookAtEntity(player.entity, true);
                    botStates.looking = true;
                }
                else {
                    botStates.looking = false;
                }
                await sleep(200);
                const goal = new goals.GoalFollow(player.entity, values.range);
                await bot.pathfinder.goto(goal);
            } 
            catch (err) {
                console.log(String(err?.message));
            }
        }
    },
    unFollowMe () {
        if (!botStates.moving) {
            return;
        }
        botStates.moving = false;
        botStates.following = false;
        bot.pathfinder.stop();
    }
};

Expected behavior

A clear and concise description of what you expected to happen. I expected the bot to... well, walk. That's all LOL

Additional context

Add any other context about the problem here. It seems like when the bot destroys the stairs, it can't even pathfind to me... weird. My server is online, you can join if you'd like. thanks :)

extremeheat commented 1 year ago

There is too much unrelated code here. Why do you believe this is a bug in mineflayer? Does it break between one version and another? If so you need to provide a minimum reproducible example otherwise there is no path to issue resolution

SonicandTailsCD commented 1 year ago

There is too much unrelated code here.

Yes, I understand. I have that for many actions.

Why do you believe this is a bug in Mineflayer?

I believe it's a bug because it was working earlier (about 10 days ago)

Does it break between one version and another?

I haven't tried that.

SonicandTailsCD commented 1 year ago

I have no idea what happened, but it's fixed?! I'm not sure why it didn't work yesterday. I'm sorry for bothering you.

SonicandTailsCD commented 1 year ago

Should I close this now?

SonicandTailsCD commented 1 year ago

Oh, wait, nevermind! HAHAHA It's happening again.

SonicandTailsCD commented 1 year ago

It keeps fixing itself! What a weird glitch.

SonicandTailsCD commented 1 year ago

I think the bug was... somehow fixed?! I'll reopen it when I get that bug again.