From d473ceb1ca63e22ba3f6d07b0912606f1c57cc50 Mon Sep 17 00:00:00 2001 From: GenerelSchwerz Date: Fri, 8 Mar 2024 17:07:28 -0500 Subject: [PATCH] basic fix to carpets --- .gitignore | 1 + src/ThePathfinder.ts | 8 ++-- src/mineflayer-specific/movements/movement.ts | 2 +- .../movements/movementExecutor.ts | 38 +++++++++++-------- .../movements/movementProviders.ts | 8 ++-- src/mineflayer-specific/world/cacheWorld.ts | 18 +++++---- src/utils.ts | 13 +++++++ 7 files changed, 57 insertions(+), 31 deletions(-) diff --git a/.gitignore b/.gitignore index 8f0e1bb..4afa5e4 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ node_modules/ dist/ yarn-* package-lock.json +*.log \ No newline at end of file diff --git a/src/ThePathfinder.ts b/src/ThePathfinder.ts index a9d20da..7656d6f 100644 --- a/src/ThePathfinder.ts +++ b/src/ThePathfinder.ts @@ -43,7 +43,7 @@ import { Block, HandlerOpts, ResetReason } from './types' import { Task } from '@nxg-org/mineflayer-util-plugin' import { reconstructPath } from './abstract/algorithms' -import { closestPointOnLineSegment, getScaffoldCount } from './utils' +import { closestPointOnLineSegment, getScaffoldCount, getNormalizedPos } from './utils' import { World } from './mineflayer-specific/world/worldInterface' export interface PathfinderOptions { @@ -444,6 +444,8 @@ export class ThePathfinder { this.abortCalculation = false delete this.resetReason + startPos = getNormalizedPos(this.bot, startPos) + this.currentMove = Move.startMove( new IdleMovement(this.bot, this.world), startPos.clone(), @@ -777,7 +779,7 @@ export class ThePathfinder { console.log('canceled') // await this.cleanupBot() // allow recovery if movement intentionall canceled. - // await this.recovery(move, path, goal, entry) + await this.recovery(move, path, goal, entry) break } else throw err } @@ -809,7 +811,7 @@ export class ThePathfinder { nextMove = path.path[ind + 1] } - const no = entry > 0 || bad + const no = entry > 5 || bad if (no || nextMove == null) { newGoal = goal } else { diff --git a/src/mineflayer-specific/movements/movement.ts b/src/mineflayer-specific/movements/movement.ts index 3937748..48d4624 100644 --- a/src/mineflayer-specific/movements/movement.ts +++ b/src/mineflayer-specific/movements/movement.ts @@ -259,7 +259,7 @@ export abstract class Movement { if (this.currentMove.remainingBlocks <= 0) return 100 if (block.block === null) return 100 // Don't know its type, but that's only replaceables so just return. - if (block.physical) return 0 // block is already physical at location. + if (block.solidFull) return 0 // block is already physical at location. const cost = this.placeCost(block) diff --git a/src/mineflayer-specific/movements/movementExecutor.ts b/src/mineflayer-specific/movements/movementExecutor.ts index 7cf1866..e5b4dc7 100644 --- a/src/mineflayer-specific/movements/movementExecutor.ts +++ b/src/mineflayer-specific/movements/movementExecutor.ts @@ -9,6 +9,7 @@ import { Movement, MovementOptions } from './movement' import { AABB, AABBUtils, Task } from '@nxg-org/mineflayer-util-plugin' import { BaseSimulator, Controller, EPhysicsCtx, EntityPhysics, EntityState, SimulationGoal } from '@nxg-org/mineflayer-physics-util' import { botStrafeMovement, botSmartMovement } from './controls' +import { getNormalizedPos } from '../../utils' // temp typing interface AbortOpts { @@ -281,8 +282,10 @@ export abstract class MovementExecutor extends Movement { // console.log(ectx.state.pos, ectx.state.isCollidedHorizontally, ectx.state.isCollidedVertically); + const normPos = getNormalizedPos(this.bot, pos) + // const pos = this.bot.entity.position - const bb0 = AABBUtils.getPlayerAABB({ position: pos, width: 0.599, height: 1.8 }) + const bb0 = AABBUtils.getPlayerAABB({ position: normPos, width: 0.599, height: 1.8 }) // bb0.extend(0, ticks === 0 ? -0.251 : -0.1, 0); // bb0.expand(-0.0001, 0, -0.0001); @@ -370,9 +373,12 @@ export abstract class MovementExecutor extends Movement { off1.translate(0, -off1.y, 0) const similarDirection = off0.normalize().dot(off1.normalize()) > 0.95 + + const normPos = getNormalizedPos(this.bot) + // console.log(similarDirection, thisMove.moveType.constructor.name, target, thisMove.entryPos, thisMove.exitPos) // if (!similarDirection) { - const bb0 = AABBUtils.getEntityAABBRaw({ position: this.bot.entity.position, width: 0.6, height: 1.8 }) + const bb0 = AABBUtils.getEntityAABBRaw({ position: normPos, width: 0.6, height: 1.8 }) const bb1bl = this.getBlockInfo(target, 0, -1, 0) const bb1 = bb1bl.getBBs() @@ -384,20 +390,20 @@ export abstract class MovementExecutor extends Movement { if (bb2.length === 0) bb2.push(AABB.fromBlock(bb2bl.position)) const bb2good = bb2bl.physical || bb2bl.liquid - // console.log( - // this.toPlaceLen(), - // bb1bl.block?.name, - // bb1, - // bb2bl.block?.name, - // bb2, - // 'test', - // bb0, - // bb1.some((b) => b.collides(bb0)), - // bb1physical, - // bb2.some((b) => b.collides(bb0)), - // bb2physical, - // bb2bl - // ) + console.log( + this.toPlaceLen(), + bb1bl.block?.name, + bb1, + bb2bl.block?.name, + bb2, + 'test', + bb0, + bb1.some((b) => b.collides(bb0)), + bb1good, + bb2.some((b) => b.collides(bb0)), + bb2good, + bb2bl + ) // console.log(bb0.collides(bb1), bb0, bb1, this.bot.entity.position.distanceTo(thisMove.entryPos)) if ((bb1.some((b) => b.collides(bb0)) && bb1good) || (bb2.some((b) => b.collides(bb0)) && bb2good)) { // console.log('yay', similarDirection, this.bot.entity.position.xzDistanceTo(target)) diff --git a/src/mineflayer-specific/movements/movementProviders.ts b/src/mineflayer-specific/movements/movementProviders.ts index a364960..67e708e 100644 --- a/src/mineflayer-specific/movements/movementProviders.ts +++ b/src/mineflayer-specific/movements/movementProviders.ts @@ -175,14 +175,14 @@ export class ForwardJump extends MovementProvider { // if (blockB.physical && !blockH.physical && !blockC.physical && (this.getNumEntitiesAt(blockB.position, 0, 1, 0) > 0)) return // It is fine if an ent falls on B so long as we don't need to replace block C // if liquid, allow swim movement up to it. - if (!blockC.physical && !blockB.liquid) { + if (!blockC.solidFull && !blockB.liquid) { if (node.remainingBlocks <= 0) return // not enough blocks to place // if (this.getNumEntitiesAt(blockC.position, 0, 0, 0) > 0) return // Check for any entities in the way of a block placement // console.log('blockC', blockC) const blockD = this.getBlockInfo(pos, dir.x, -1, dir.z) - if (!blockD.physical) { + if (!blockD.solidFull) { if (node.remainingBlocks <= 1) return // not enough blocks to place // if (this.getNumEntitiesAt(blockD.position, 0, 0, 0) > 0) return // Check for any entities in the way of a block placement @@ -380,12 +380,12 @@ export class StraightUp extends MovementProvider { toBreak.push(BreakHandler.fromVec(block1.position, 'solid')) } + if ((cost += this.safeOrPlace(block1, toPlace, 'solid')) > 100) return + const block0 = this.getBlockInfo(node, 0, -1, 0) if (block0.liquid) return // cant build in water if (block0.physical && block0.height - node.y < -0.2) return // cannot jump-place from a half block - - if ((cost += this.safeOrPlace(block1, toPlace, 'solid')) > 100) return } } diff --git a/src/mineflayer-specific/world/cacheWorld.ts b/src/mineflayer-specific/world/cacheWorld.ts index 8f3a15c..5f65e83 100644 --- a/src/mineflayer-specific/world/cacheWorld.ts +++ b/src/mineflayer-specific/world/cacheWorld.ts @@ -50,6 +50,7 @@ export class BlockInfo { return this._fallBlockOver } + public readonly solidFull: boolean public readonly isInvalid = this.type === -1 constructor ( @@ -65,7 +66,10 @@ export class BlockInfo { // comp only public readonly type: number, public readonly block: Block | null = null - ) {} + ) { + // this.solidFull = physical + this.solidFull = this.height - this.position.y >= 1 && this.physical + } static init (registry: MCData): void { if (BlockInfo.initialized) return @@ -398,9 +402,9 @@ export class CacheSyncWorld implements WorldType { } getBlock (pos: Vec3): Block | null { - if (!this.enabled) { - return this.world.getBlock(pos) as unknown as Block - } + // if (!this.enabled) { + // return this.world.getBlock(pos) as unknown as Block + // } this.cacheCalls++ pos = pos.floored() const key = `${pos.x}:${pos.y}:${pos.z}` @@ -417,9 +421,9 @@ export class CacheSyncWorld implements WorldType { // this.cacheCalls++ // return BlockInfo.fromBlock(this.world.getBlock(pos)) - if (!this.enabled) { - return BlockInfo.fromBlock(this.world.getBlock(pos)) - } + // if (!this.enabled) { + // return BlockInfo.fromBlock(this.world.getBlock(pos)) + // } this.cacheCalls++ pos = pos.floored() const key = `${pos.x}:${pos.y}:${pos.z}` diff --git a/src/utils.ts b/src/utils.ts index 42d7ab3..0d9d41c 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -55,6 +55,19 @@ export function closestPointOnLineSegment (point: Vec3, segmentStart: Vec3, segm return segmentStart.plus(segmentEnd.minus(segmentStart).scaled(t)) } +export function getNormalizedPos (bot: Bot, startPos?: Vec3): Vec3 { + if (!BlockInfo.initialized) throw new Error('BlockInfo not initialized') + // check if we are on carpet + const pos = startPos ?? bot.entity.position.clone() + + const block = bot.pathfinder.world.getBlockInfo(pos) + if (BlockInfo.carpets.has(block.type)) { + return pos.floor() + } + + return pos +} + export async function onceWithCleanup ( emitter: NodeJS.EventEmitter, event: string,