mineflayer-statemachine icon indicating copy to clipboard operation
mineflayer-statemachine copied to clipboard

Dependencies issue

Open alexanderbkl opened this issue 1 year ago • 1 comments

I'm getting this error when bot needs to scaffold:

const offset = (b && dy > 0.001 && bot.entity.onGround && !stateMovements.emptyBlocks.has(b.type)) ? 1 : 0 ^ TypeError: Cannot read properties of undefined (reading 'has') at Object.bot.pathfinder.getPathFromTo (C:\Users\Desktop\prismarine\mineflayer\node_modules\mineflayer-pathfinder\index.js:83:93)

Here is the code I'm using:


const mineflayer = require('mineflayer');
const { pathfinder, Movements, goals } = require('mineflayer-pathfinder');
//Vec3
const Vec3 = require('vec3');

const bot = mineflayer.createBot({ host: 'mc.blurkit.net', port: 25565, username: 'OneKe' })

//const mcData = require('minecraft-data')(bot.version);

// load plugins
bot.loadPlugin(pathfinder);
bot.loadPlugin(require('mineflayer-pathfinder').pathfinder);




//send helloworld to chat

let loggedIn = false;

var jsonMsg;


bot.on('message', async (jsonMsg) => new Promise((resolve, reject) => {


    if (!loggedIn) {
        setTimeout(resolve, 100)

        bot.once('physicTick', () => {

          

                console.log("starting to login2")
                bot.chat('/login password');

                console.log("starting to login3")

            
        })



        console.log('logging in')

        //if jsonmsg contains "/tpbypass", then write bot.chat('/login password')
        if (jsonMsg.toString().includes("[»] Ya has iniciado seción!")) {
            //stop this listener
            loggedIn = true;
            bot.removeListener('physicTick', () => { })
        }
    }


    if (jsonMsg.toString() != "" || jsonMsg.toString() != null || jsonMsg.toString() != undefined || !jsonMsg.toString.includes("        ")) {
        console.log("jsonmsg: " + jsonMsg)
        this.jsonMsg = jsonMsg.toString();
    }


}));






// Log errors and kick reasons:
bot.on('kicked', console.log)
bot.on('error', console.log)



//wait for login to complete




//wait for spawn to complete
bot.on('spawn', () => {
    console.log("starting to login5")


    //wait for inventory to complete

    let item = bot.inventory.findInventoryItem('compass')

    //equip hotbar to slot number 5


    bot.inventory.items().forEach(item => {

        console.log(item.name)


        if (item.name === 'compass') {

            //select compass to hotbar
            bot.inventory.updateSlot(item.slot, item)
            //equip compass to hotbar
            bot.equip(item, 'hand')



            bot.activateItem()

            //a menu will pop up, display the menu
            bot.once('windowOpen', (window) => {

                console.log('preparin to click slot')
                bot.clickWindow(13, 1, 0)
                console.log("left click grass block")

                //wait for inventory to complete
                bot.once('windowOpen', (window) => {
                    console.log("windowOpen 2")
                    bot.clickWindow(15, 1, 0)

                    bot.once('spawn', () => {

                        console.log("starting to login6")



                        //display everything inside inventory
                        bot.inventory.items().forEach(item => {
                            console.log("item: " + item.name);
                        }
                        );

                        const {
                            StateTransition,
                            BotStateMachine,
                            EntityFilters,
                            BehaviorFollowEntity,
                            BehaviorLookAtEntity,
                            BehaviorGetClosestEntity,
                            NestedStateMachine } = require("mineflayer-statemachine");

                        //go to nearest player
                        const playerCI = bot.players['vitzel'];
                        const target = playerCI?.entity;
                        //const RANGE_GOAL = 3 // get within this radius of the player
                        //const movements = new Movements(bot, mcData);
                        //bot.pathfinder.setMovements(movements);

                        if (playerCI) {


                            //let { x: playerX, y: playerY, z: playerZ } = target.position

                            //let goal = new goals.GoalNear(playerX, playerY, playerZ, RANGE_GOAL)

                            const targets = {};
                            const getClosestPlayer = new BehaviorGetClosestEntity(bot, targets, EntityFilters().PlayersOnly);
                            const followPlayer = new BehaviorFollowEntity(bot, targets);
                            const lookAtPlayer = new BehaviorLookAtEntity(bot, targets);

                            // Create our transitions
                            const transitions = [

                                // We want to start following the player immediately after finding them.
                                // Since getClosestPlayer finishes instantly, shouldTransition() should always return true.
                                new StateTransition({
                                    parent: getClosestPlayer,
                                    child: followPlayer,
                                    shouldTransition: () => true,
                                }),

                                // If the distance to the player is less than two blocks, switch from the followPlayer
                                // state to the lookAtPlayer state.
                                new StateTransition({
                                    parent: followPlayer,
                                    child: lookAtPlayer,
                                    shouldTransition: () => followPlayer.distanceToTarget() < 2,
                                }),

                                // If the distance to the player is more than two blocks, switch from the lookAtPlayer
                                // state to the followPlayer state.
                                new StateTransition({
                                    parent: lookAtPlayer,
                                    child: followPlayer,
                                    shouldTransition: () => lookAtPlayer.distanceToTarget() >= 2,
                                }),
                            ];

                            // Now we just wrap our transition list in a nested state machine layer. We want the bot
                            // to start on the getClosestPlayer state, so we'll specify that here.
                            const rootLayer = new NestedStateMachine(transitions, getClosestPlayer);

                            // We can start our state machine simply by creating a new instance.
                            new BotStateMachine(bot, rootLayer);


                        }
                    });
                });

            });
        }

    });


});

alexanderbkl avatar Jan 08 '23 09:01 alexanderbkl

Fixed on mineflayer-pathfinder>index.js>inject()>getPathFromTo()

Before:

    let start
    if (options.startMove) {
      start = options.startMove
    } else {
      const p = startPos.floored()
      const dy = startPos.y - p.y
      const b = bot.blockAt(p) // The block we are standing in
      // Offset the floored bot position by one if we are standing on a block that has not the full height but is solid
      const offset = (b && dy > 0.001 && bot.entity.onGround && !stateMovements.emptyBlocks.has(b.type)) ? 1 : 0
      start = new Move(p.x, p.y + offset, p.z, movements.countScaffoldingItems(), 0)
    }

After:

    let start
    if (options.startMove) {
      start = options.startMove
    } else {
      const p = startPos.floored()
      const dy = startPos.y - p.y
      const b = bot.blockAt(p) // The block we are standing in
      // Offset the floored bot position by one if we are standing on a block that has not the full height but is solid
      // This is to prevent the bot from falling through the block
      if (dy > 0 && dy < 1 && b && b.boundingBox === 'block') {
        start = p.offset(0, 1, 0)
      }
      start = p
      
    }

But now has invalid packet when falling in water.

alexanderbkl avatar Jan 08 '23 10:01 alexanderbkl