mineflayer icon indicating copy to clipboard operation
mineflayer copied to clipboard

nearestEntity ignoring python lambda function for match

Open kolbytn opened this issue 1 year ago • 1 comments

  • [x] The FAQ doesn't contain a resolution to my issue

Versions

  • mineflayer: 4.9.0
  • server: vanilla 1.19.3
  • node: 18.6.3

Detailed description of a problem

When using the nearestEntity function via python, the function always returns any nearest entity and ignores the match argument.

Your current code

My code:

nearest = bot.nearestEntity(lambda x: x.name == "cow")
print(nearest)

Outputs:

Entity {
  _events: [Object: null prototype] {},
  _eventsCount: 0,
  _maxListeners: undefined,
  id: 150,
  position: Vec3 { x: 14.283650489960799, y: 93, z: 11.131849115241222 },
  velocity: Vec3 { x: 0, y: 0, z: 0 },
  yaw: 3.3870295796514958,
  pitch: -0.1963495408493623,
  onGround: true,
  height: 1.62,
  width: 0.6,
  effects: {},
  equipment: [ <5 empty items> ],
  heldItem: undefined,
  isValid: true,
  metadata: [ <9 empty items>, 20, <6 empty items>, 18, 127 ],
  type: 'player',
  name: 'player',
  username: '',
  uuid: '38f91685-7bcb-42aa-bda7-544294970337',
  dataBlobs: undefined,
  attributes: {
    'minecraft:generic.attack_speed': { value: 4, modifiers: [] },
    'minecraft:generic.movement_speed': { value: 0.10000000149011612, modifiers: [] }
  },
  headYaw: 3.3870295796514958,
  [Symbol(kCapture)]: false
}

Expected behavior

It should output the neatest cow entity or None.

Additional context

I'm using mineflayer via python 3.7.8

kolbytn avatar Jul 10 '23 22:07 kolbytn

Yeah this has to do with how jspybridge works. With he way it makes call to functions, they are treated as asynchronous functions by the javascript interpreter. Because of this, functions that use synchronous callbacks all end up with Promises instead of the intended result. (I'll be real and say I actually have no clue how jspybridge works but python functions do appear as async)

The fix currently is to go into mineflayers source code and change the functions you use into asynchronous functions and avoid using functions with callbacks. You can create your own nearestEntity function in python pretty easily.

I just wrote this and haven't tested it but it should be fine

def nearestEntity(matcher):
  smallestDist = 9e9
  closestEntity = None
  for entity in bot.entities.values():
    dist = entitiy.position.distanceSquared(bot.entity.position)
    if dist < smallestDist and entity != bot.entity:
      smallestDist = dist
      closestEntity = entity
  return entity

WhoTho avatar Aug 24 '23 17:08 WhoTho