UNPKG

@nxg-org/mineflayer-physics-util

Version:

Provides functionality for more accurate entity and projectile tracking.

467 lines (466 loc) 20.8 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.ControlStateHandler = exports.PlayerState = exports.EntityDimensions = void 0; exports.convInpToAxes = convInpToAxes; const mineflayer_util_plugin_1 = require("@nxg-org/mineflayer-util-plugin"); const nbt = __importStar(require("prismarine-nbt")); const vec3_1 = require("vec3"); const physicsUtils_1 = require("../../util/physicsUtils"); const playerControls_1 = require("../player/playerControls"); Object.defineProperty(exports, "ControlStateHandler", { enumerable: true, get: function () { return playerControls_1.ControlStateHandler; } }); const poses_1 = require("./poses"); const _1 = require("."); function convInpToAxes(player) { return { forward: player.control.forward - player.control.back, strafe: player.control.left - player.control.right, }; } const defaultMoves = playerControls_1.ControlStateHandler.DEFAULT(); //Utility class that wraps PlayerPoses. class EntityDimensions { constructor(width, height, fixed) { this.width = width; this.height = height; this.fixed = fixed; } static scalable(f, f2) { return new EntityDimensions(f, f2, false); } static fixed(f, f2) { return new EntityDimensions(f, f2, true); } makeBoundingBox(vec3) { return this.makeBoundingBoxCoords(vec3.x, vec3.y, vec3.z); } makeBoundingBoxCoords(d, d2, d3) { const f = this.width / 2.0; const f2 = this.height; return new mineflayer_util_plugin_1.AABB(d - f, d2, d3 - f, d + f, d2 + f2, d3 + f); } scale(f) { return this.scaleRaw(f, f); } scaleRaw(f, f2) { if (this.fixed || (f == 1.0 && f2 == 1.0)) { return this; } return EntityDimensions.scalable(this.width * f, this.height * f2); } toString() { return "EntityDimensions w=" + this.width + ", h=" + this.height + ", fixed=" + this.fixed; } } exports.EntityDimensions = EntityDimensions; /** * Looking at this code, it's too specified towards players. * * I will eventually split this code into PlayerState and bot.entityState, where bot.entityState contains fewer controls. */ class PlayerState { get sprinting() { return this._sprinting; } set sprinting(value) { // console.trace('set sprinting', value) this._sprinting = value; } get onGroundWithoutSupportingBlock() { return this.onGround && !this.supportingBlockPos; } get height() { return poses_1.playerPoseCtx[this.pose].height; } get eyeHeight() { switch (this.pose) { case poses_1.PlayerPoses.STANDING: return 1.62; case poses_1.PlayerPoses.SNEAKING: return 1.27; case poses_1.PlayerPoses.DYING: case poses_1.PlayerPoses.SLEEPING: case poses_1.PlayerPoses.SWIMMING: case poses_1.PlayerPoses.FALL_FLYING: case poses_1.PlayerPoses.SPIN_ATTACK: return 0.4; default: return 1.62; } } get halfWidth() { return poses_1.playerPoseCtx[this.pose].width / 2; } constructor(ctx, bot, control) { this.age = 0; this.onGround = false; this.onClimbable = false; this.isInWater = false; this.isUnderWater = false; this.isInLava = false; this.isUnderLava = false; this.isInWeb = false; this.elytraFlying = false; this.elytraEquipped = false; this.fireworkRocketDuration = 0; this.isCollidedHorizontally = false; this.isCollidedHorizontallyMinor = false; this.isCollidedVertically = false; this.supportingBlockPos = null; this.stuckSpeedMultiplier = new vec3_1.Vec3(0, 0, 0); this.jumpTicks = 0; this.jumpQueued = false; this.sprintTriggerTime = 0; this.flyJumpTriggerTime = 0; this.sneakCollision = false; this.attributes = {}; this.yaw = 0; this.pitch = 0; this.control = defaultMoves; this.prevControl = defaultMoves; this.heading = { forward: 0, strafe: 0 }; this.prevHeading = { forward: 0, strafe: 0 }; this.isUsingItem = false; this.isUsingMainHand = false; this.isUsingOffHand = false; this.jumpBoost = 0; this.speed = 0; this.slowness = 0; this.dolphinsGrace = 0; this.slowFalling = 0; this.levitation = 0; this.blindness = 0; this.depthStrider = 0; this.swiftSneak = 0; this.soulSpeed = 0; this.effects = []; this.pose = poses_1.PlayerPoses.STANDING; this.gameMode = "survival"; this.food = 0; // the below fields are abilities mineflayer is supposed to store. /** * TODO: proper impl. */ this.mayFly = false; /** * TODO: proper impl. */ this.flying = false; /** * TODO: proper impl. */ this.swimming = false; /** * TODO: proper impl. */ this._sprinting = false; /** * TODO: proper impl. */ this.crouching = false; /** * TODO: proper impl. */ this.fallFlying = false; /** * TODO: proper impl. */ this.flySpeed = 0; this.supportFeature = (0, physicsUtils_1.makeSupportFeature)(ctx.data); this.ctx = ctx; this.bot = bot; this.pos = bot.entity.position.clone(); this.vel = bot.entity.velocity.clone(); this.statusEffectNames = (0, physicsUtils_1.getStatusEffectNamesForVersion)(this.supportFeature); this.update(bot, playerControls_1.ControlStateHandler.COPY_BOT(bot)); } update(bot, control) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p; // const bot.entity = bot instanceof bot.entity ? bot : bot.entity; // Input / Outputs this.pos.set(bot.entity.position.x, bot.entity.position.y, bot.entity.position.z); this.vel.set(bot.entity.velocity.x, bot.entity.velocity.y, bot.entity.velocity.z); this.supportingBlockPos = (_a = bot.entity.supportingBlockPos) !== null && _a !== void 0 ? _a : null; this.onGround = bot.entity.onGround; this.onClimbable = bot.entity.onClimbable; this.isInWater = bot.entity.isInWater; this.isUnderWater = bot.entity.isUnderWater; this.isInLava = bot.entity.isInLava; this.isUnderLava = bot.entity.isUnderLava; this.isInWeb = bot.entity.isInWeb; this.elytraFlying = bot.entity.elytraFlying; this.elytraEquipped = ((_b = bot.inventory.slots[bot.getEquipmentDestSlot('torso')]) === null || _b === void 0 ? void 0 : _b.name) === 'elytra'; this.fireworkRocketDuration = bot.fireworkRocketDuration; this.isCollidedHorizontally = bot.entity.isCollidedHorizontally; this.isCollidedHorizontallyMinor = bot.entity.isCollidedHorizontallyMinor; this.isCollidedVertically = bot.entity.isCollidedVertically; // dunno what to do about these, ngl. this.jumpTicks = (_c = bot.jumpTicks) !== null && _c !== void 0 ? _c : 0; this.jumpQueued = (_d = bot.jumpQueued) !== null && _d !== void 0 ? _d : false; this.flyJumpTriggerTime = (_e = bot.flyJumpTriggerTime) !== null && _e !== void 0 ? _e : 0; this.sprintTriggerTime = (_f = bot.sprintTriggerTime) !== null && _f !== void 0 ? _f : 0; // Input only (not modified) this.attributes = bot.entity.attributes; this.yaw = bot.entity.yaw; this.pitch = bot.entity.pitch; this.control = control !== null && control !== void 0 ? control : playerControls_1.ControlStateHandler.COPY_BOT(bot); // prevControl only updated internally. this.isUsingItem = bot.usingHeldItem; /* || isEntityUsingItem(bot.entity, this.ctx.supportFeature); */ this.isUsingMainHand = !(0, physicsUtils_1.whichHandIsEntityUsingBoolean)(bot.entity, this.ctx.supportFeature) && this.isUsingItem; this.isUsingOffHand = (0, physicsUtils_1.whichHandIsEntityUsingBoolean)(bot.entity, this.ctx.supportFeature) && this.isUsingItem; // effects this.effects = bot.entity.effects; this.jumpBoost = this.ctx.getEffectLevel(physicsUtils_1.CheapEffects.JUMP_BOOST, this.effects); this.speed = this.ctx.getEffectLevel(physicsUtils_1.CheapEffects.SPEED, this.effects); this.slowness = this.ctx.getEffectLevel(physicsUtils_1.CheapEffects.SLOWNESS, this.effects); this.dolphinsGrace = this.ctx.getEffectLevel(physicsUtils_1.CheapEffects.DOLPHINS_GRACE, this.effects); this.slowFalling = this.ctx.getEffectLevel(physicsUtils_1.CheapEffects.SLOW_FALLING, this.effects); this.levitation = this.ctx.getEffectLevel(physicsUtils_1.CheapEffects.LEVITATION, this.effects); // armour enchantments //const boots = bot.inventory.slots[8]; const boots = bot.entity.equipment[5]; if (boots && boots.nbt) { const simplifiedNbt = nbt.simplify(boots.nbt); const enchantments = (_h = (_g = simplifiedNbt.Enchantments) !== null && _g !== void 0 ? _g : simplifiedNbt.ench) !== null && _h !== void 0 ? _h : []; this.depthStrider = this.ctx.getEnchantmentLevel(physicsUtils_1.CheapEnchantments.DEPTH_STRIDER, enchantments); this.soulSpeed = this.ctx.getEnchantmentLevel(physicsUtils_1.CheapEnchantments.SOUL_SPEED, enchantments); } else { this.depthStrider = 0; this.soulSpeed = 0; } const leggings = bot.entity.equipment[3]; if (leggings && leggings.nbt) { const simplifiedNbt = nbt.simplify(leggings.nbt); const enchantments = (_k = (_j = simplifiedNbt.Enchantments) !== null && _j !== void 0 ? _j : simplifiedNbt.ench) !== null && _k !== void 0 ? _k : []; this.swiftSneak = this.ctx.getEnchantmentLevel(physicsUtils_1.CheapEnchantments.SWIFT_SNEAK, enchantments); } else { this.swiftSneak = 0; } this.pose = (0, _1.getPose)(bot.entity); this.gameMode = bot.game.gameMode; this.food = bot.food; // TODO: this.swimming = (_l = bot.entity.swimming) !== null && _l !== void 0 ? _l : false; this.sprinting = (_m = bot.entity.sprinting) !== null && _m !== void 0 ? _m : false; this.crouching = (_o = bot.entity.crouching) !== null && _o !== void 0 ? _o : false; this.fallFlying = (_p = bot.entity.fallFlying) !== null && _p !== void 0 ? _p : false; switch (bot.game.gameMode) { case "creative": this.flySpeed = 0.05; this.mayFly = true; break; case "spectator": this.flySpeed = 0.1; this.mayFly = true; break; case "survival": case "adventure": this.flySpeed = 0; this.mayFly = bot.entity.canFly; break; default: throw new Error("Unknown game mode: " + bot.game.gameMode); } this.flying = !!bot.entity.flying && this.mayFly; return this; } apply(bot) { var _a, _b, _c, _d, _e; // const bot.entity = bot instanceof bot.entity ? bot : bot.entity; bot.entity.position.set(this.pos.x, this.pos.y, this.pos.z); bot.entity.velocity.set(this.vel.x, this.vel.y, this.vel.z); bot.entity.onGround = this.onGround; bot.entity.onClimbable = this.onClimbable; bot.entity.isInWater = this.isInWater; bot.entity.isUnderWater = this.isUnderWater; bot.entity.isInLava = this.isInLava; bot.entity.isUnderLava = this.isUnderLava; bot.entity.isInWeb = this.isInWeb; bot.entity.elytraFlying = this.elytraFlying; bot.entity.elytraEquipped = this.elytraEquipped; bot.fireworkRocketDuration = this.fireworkRocketDuration; bot.entity.isCollidedHorizontally = this.isCollidedHorizontally; bot.entity.isCollidedHorizontallyMinor = this.isCollidedHorizontallyMinor; bot.entity.isCollidedVertically = this.isCollidedVertically; bot.entity.supportingBlockPos = this.supportingBlockPos; // dunno what to do about these, ngl. bot.jumpTicks = this.jumpTicks; bot.jumpQueued = this.jumpQueued; bot.flyJumpTriggerTime = this.flyJumpTriggerTime; bot.sprintTriggerTime = this.sprintTriggerTime; bot.entity.yaw = this.yaw; bot.entity.pitch = this.pitch; Object.assign(bot.entity, this.pose); bot.game.gameMode = this.gameMode; // this should never actually be in charge. bot.food = this.food; // this should also never actually be in charge. bot.entity.flying = (_a = this.flying) !== null && _a !== void 0 ? _a : false; bot.entity.swimming = (_b = this.swimming) !== null && _b !== void 0 ? _b : false; bot.entity.sprinting = (_c = this.sprinting) !== null && _c !== void 0 ? _c : false; bot.entity.crouching = (_d = this.crouching) !== null && _d !== void 0 ? _d : false; bot.entity.fallFlying = (_e = this.fallFlying) !== null && _e !== void 0 ? _e : false; bot.entity.attributes = this.attributes; this.control.applyControls(bot); bot.entity.prevControl = this.prevControl; } clone() { var _a, _b, _c, _d; const tmp = new PlayerState(this.ctx, this.bot, this.control); tmp.pos.set(this.pos.x, this.pos.y, this.pos.z); tmp.vel.set(this.vel.x, this.vel.y, this.vel.z); tmp.onGround = this.onGround; tmp.onClimbable = this.onClimbable; tmp.isInWater = this.isInWater; tmp.isUnderWater = this.isUnderWater; tmp.isInLava = this.isInLava; tmp.isUnderLava = this.isUnderLava; tmp.isInWeb = this.isInWeb; tmp.elytraFlying = this.elytraFlying; tmp.elytraEquipped = this.elytraEquipped; tmp.fireworkRocketDuration = this.fireworkRocketDuration; tmp.isCollidedHorizontally = this.isCollidedHorizontally; tmp.isCollidedHorizontallyMinor = this.isCollidedHorizontallyMinor; tmp.isCollidedVertically = this.isCollidedVertically; tmp.supportingBlockPos = this.supportingBlockPos; tmp.sneakCollision = false; //TODO //not sure what to do here, ngl. tmp.jumpTicks = (_a = this.jumpTicks) !== null && _a !== void 0 ? _a : 0; tmp.jumpQueued = (_b = this.jumpQueued) !== null && _b !== void 0 ? _b : false; tmp.flyJumpTriggerTime = (_c = this.flyJumpTriggerTime) !== null && _c !== void 0 ? _c : 0; tmp.sprintTriggerTime = (_d = this.sprintTriggerTime) !== null && _d !== void 0 ? _d : 0; // Input only (not modified) tmp.attributes = this.attributes; tmp.yaw = this.yaw; tmp.pitch = this.pitch; tmp.control = this.control.clone(); tmp.prevControl = this.prevControl.clone(); tmp.isUsingItem = this.isUsingItem; tmp.isUsingMainHand = this.isUsingMainHand; tmp.isUsingOffHand = this.isUsingOffHand; // effects tmp.effects = this.effects; tmp.statusEffectNames = this.statusEffectNames; tmp.jumpBoost = this.jumpBoost; tmp.speed = this.speed; tmp.slowness = this.slowness; tmp.dolphinsGrace = this.dolphinsGrace; tmp.slowFalling = this.slowFalling; tmp.levitation = this.levitation; tmp.blindness = this.blindness; tmp.soulSpeed = this.soulSpeed; tmp.swiftSneak = this.swiftSneak; tmp.depthStrider = this.depthStrider; tmp.pose = this.pose; tmp.gameMode = this.gameMode; tmp.flying = this.flying; tmp.swimming = this.swimming; tmp.sprinting = this.sprinting; tmp.crouching = this.crouching; tmp.fallFlying = this.fallFlying; tmp.food = this.food; return tmp; } merge(other) { var _a, _b, _c, _d; this.pos.set(other.pos.x, other.pos.y, other.pos.z); this.vel.set(other.vel.x, other.vel.y, other.vel.z); this.onGround = other.onGround; this.onClimbable = other.onClimbable; this.isInWater = other.isInWater; this.isUnderWater = other.isUnderWater; this.isInLava = other.isInLava; this.isUnderLava = other.isUnderLava; this.isInWeb = other.isInWeb; this.elytraFlying = other.elytraFlying; this.elytraEquipped = other.elytraEquipped; this.fireworkRocketDuration = other.fireworkRocketDuration; this.isCollidedHorizontally = other.isCollidedHorizontally; this.isCollidedHorizontallyMinor = other.isCollidedHorizontallyMinor; this.isCollidedVertically = other.isCollidedVertically; this.supportingBlockPos = other.supportingBlockPos; this.sneakCollision = false; //TODO //not sure what to do here, ngl. this.jumpTicks = (_a = other.jumpTicks) !== null && _a !== void 0 ? _a : 0; this.jumpQueued = (_b = other.jumpQueued) !== null && _b !== void 0 ? _b : false; this.flyJumpTriggerTime = (_c = other.flyJumpTriggerTime) !== null && _c !== void 0 ? _c : 0; this.sprintTriggerTime = (_d = other.sprintTriggerTime) !== null && _d !== void 0 ? _d : 0; // Input only (not modified) this.attributes = other.attributes; this.yaw = other.yaw; this.pitch = other.pitch; this.control = other.control.clone(); this.prevControl = other.prevControl.clone(); this.isUsingItem = other.isUsingItem; this.isUsingMainHand = other.isUsingMainHand; this.isUsingOffHand = other.isUsingOffHand; // effects this.effects = other.effects; this.statusEffectNames = other.statusEffectNames; this.jumpBoost = other.jumpBoost; this.speed = other.speed; this.slowness = other.slowness; this.dolphinsGrace = other.dolphinsGrace; this.slowFalling = other.slowFalling; this.swiftSneak = other.swiftSneak; this.soulSpeed = other.soulSpeed; this.levitation = other.levitation; this.depthStrider = other.depthStrider; this.pose = other.pose; this.gameMode = other.gameMode; this.flying = other.flying; this.swimming = other.swimming; this.sprinting = other.sprinting; this.crouching = other.crouching; this.food = other.food; return this; } getBB() { const w = this.halfWidth; return new mineflayer_util_plugin_1.AABB(this.pos.x - w, this.pos.y, this.pos.z - w, this.pos.x + w, this.pos.y + this.height, this.pos.z + w); } lookAt(vec3) { const dx = vec3.x - this.pos.x; const dy = vec3.y - this.pos.y; const dz = vec3.z - this.pos.z; this.yaw = Math.atan2(dz, dx) * 180 / Math.PI - 90; this.pitch = -Math.atan2(dy, Math.sqrt(dx * dx + dz * dz)) * 180 / Math.PI; console.log(this.yaw, this.pitch); } look(yaw, pitch) { this.yaw = yaw; this.pitch = pitch; } } exports.PlayerState = PlayerState;