@nxg-org/mineflayer-util-plugin 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/LICENSE +674 -0
  2. package/lib/WorldFunctions.d.ts +10 -0
  3. package/lib/WorldFunctions.js +18 -0
  4. package/lib/calcs/aabb.d.ts +36 -0
  5. package/lib/calcs/aabb.js +194 -0
  6. package/lib/commonSense.d.ts +22 -0
  7. package/lib/commonSense.js +220 -0
  8. package/lib/customImplementations/inventory.d.ts +10 -0
  9. package/lib/customImplementations/inventory.js +95 -0
  10. package/lib/entityFunctions.d.ts +36 -0
  11. package/lib/entityFunctions.js +78 -0
  12. package/lib/filterFunctions.d.ts +23 -0
  13. package/lib/filterFunctions.js +45 -0
  14. package/lib/index.d.ts +27 -0
  15. package/lib/index.js +7 -0
  16. package/lib/inventoryFunctions.d.ts +45 -0
  17. package/lib/inventoryFunctions.js +208 -0
  18. package/lib/mathUtil.d.ts +23 -0
  19. package/lib/mathUtil.js +49 -0
  20. package/lib/movementFunctions.d.ts +43 -0
  21. package/lib/movementFunctions.js +109 -0
  22. package/lib/predictiveFunctions.d.ts +25 -0
  23. package/lib/predictiveFunctions.js +172 -0
  24. package/lib/utilFunctions.d.ts +50 -0
  25. package/lib/utilFunctions.js +140 -0
  26. package/lib/worldRelated/predictiveWorld.d.ts +41 -0
  27. package/lib/worldRelated/predictiveWorld.js +108 -0
  28. package/lib/worldRelated/raycastIterator.d.ts +45 -0
  29. package/lib/worldRelated/raycastIterator.js +114 -0
  30. package/package.json +33 -0
  31. package/src/WorldFunctions.ts +19 -0
  32. package/src/calcs/aabb.ts +218 -0
  33. package/src/commonSense.ts +189 -0
  34. package/src/customImplementations/inventory.ts +90 -0
  35. package/src/entityFunctions.ts +71 -0
  36. package/src/filterFunctions.ts +54 -0
  37. package/src/index.ts +29 -0
  38. package/src/inventoryFunctions.ts +187 -0
  39. package/src/mathUtil.ts +56 -0
  40. package/src/movementFunctions.ts +116 -0
  41. package/src/predictiveFunctions.ts +187 -0
  42. package/src/utilFunctions.ts +152 -0
  43. package/src/worldRelated/predictiveWorld.ts +109 -0
  44. package/src/worldRelated/raycastIterator.ts +136 -0
  45. package/tsconfig.json +17 -0
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RaycastIterator = exports.BlockFace = void 0;
4
+ const vec3_1 = require("vec3");
5
+ var BlockFace;
6
+ (function (BlockFace) {
7
+ BlockFace[BlockFace["UNKNOWN"] = -999] = "UNKNOWN";
8
+ BlockFace[BlockFace["BOTTOM"] = 0] = "BOTTOM";
9
+ BlockFace[BlockFace["TOP"] = 1] = "TOP";
10
+ BlockFace[BlockFace["NORTH"] = 2] = "NORTH";
11
+ BlockFace[BlockFace["SOUTH"] = 3] = "SOUTH";
12
+ BlockFace[BlockFace["WEST"] = 4] = "WEST";
13
+ BlockFace[BlockFace["EAST"] = 5] = "EAST";
14
+ })(BlockFace = exports.BlockFace || (exports.BlockFace = {}));
15
+ class RaycastIterator {
16
+ constructor(pos, dir, maxDistance) {
17
+ this.block = {
18
+ x: Math.floor(pos.x),
19
+ y: Math.floor(pos.y),
20
+ z: Math.floor(pos.z),
21
+ face: BlockFace.UNKNOWN,
22
+ };
23
+ this.blockVec = new vec3_1.Vec3(Math.floor(pos.x), Math.floor(pos.y), Math.floor(pos.z));
24
+ this.pos = pos;
25
+ this.dir = dir;
26
+ this.invDirX = dir.x === 0 ? Number.MAX_VALUE : 1 / dir.x;
27
+ this.invDirY = dir.y === 0 ? Number.MAX_VALUE : 1 / dir.y;
28
+ this.invDirZ = dir.z === 0 ? Number.MAX_VALUE : 1 / dir.z;
29
+ this.stepX = Math.sign(dir.x);
30
+ this.stepY = Math.sign(dir.y);
31
+ this.stepZ = Math.sign(dir.z);
32
+ this.tDeltaX = dir.x === 0 ? Number.MAX_VALUE : Math.abs(1 / dir.x);
33
+ this.tDeltaY = dir.y === 0 ? Number.MAX_VALUE : Math.abs(1 / dir.y);
34
+ this.tDeltaZ = dir.z === 0 ? Number.MAX_VALUE : Math.abs(1 / dir.z);
35
+ this.tMaxX = dir.x === 0 ? Number.MAX_VALUE : Math.abs((this.block.x + (dir.x > 0 ? 1 : 0) - pos.x) / dir.x);
36
+ this.tMaxY = dir.y === 0 ? Number.MAX_VALUE : Math.abs((this.block.y + (dir.y > 0 ? 1 : 0) - pos.y) / dir.y);
37
+ this.tMaxZ = dir.z === 0 ? Number.MAX_VALUE : Math.abs((this.block.z + (dir.z > 0 ? 1 : 0) - pos.z) / dir.z);
38
+ this.maxDistance = maxDistance;
39
+ }
40
+ // Returns null if none of the shapes is intersected, otherwise returns intersect pos and face
41
+ // shapes are translated by offset
42
+ //[x0: number,y0: number,z0: number,x1:number,y1:number,z1:number][]
43
+ intersect(shapes, offset) {
44
+ // Shapes is an array of shapes, each in the form of: [x0, y0, z0, x1, y1, z1]
45
+ let t = Number.MAX_VALUE;
46
+ let f = BlockFace.UNKNOWN;
47
+ const p = this.pos.minus(offset);
48
+ for (const shape of shapes) {
49
+ let tmin = (shape[this.invDirX > 0 ? 0 : 3] - p.x) * this.invDirX;
50
+ let tmax = (shape[this.invDirX > 0 ? 3 : 0] - p.x) * this.invDirX;
51
+ const tymin = (shape[this.invDirY > 0 ? 1 : 4] - p.y) * this.invDirY;
52
+ const tymax = (shape[this.invDirY > 0 ? 4 : 1] - p.y) * this.invDirY;
53
+ let face = this.stepX > 0 ? BlockFace.WEST : BlockFace.EAST;
54
+ if (tmin > tymax || tymin > tmax)
55
+ continue;
56
+ if (tymin > tmin) {
57
+ tmin = tymin;
58
+ face = this.stepY > 0 ? BlockFace.BOTTOM : BlockFace.TOP;
59
+ }
60
+ if (tymax < tmax)
61
+ tmax = tymax;
62
+ const tzmin = (shape[this.invDirZ > 0 ? 2 : 5] - p.z) * this.invDirZ;
63
+ const tzmax = (shape[this.invDirZ > 0 ? 5 : 2] - p.z) * this.invDirZ;
64
+ if (tmin > tzmax || tzmin > tmax)
65
+ continue;
66
+ if (tzmin > tmin) {
67
+ tmin = tzmin;
68
+ face = this.stepZ > 0 ? BlockFace.NORTH : BlockFace.SOUTH;
69
+ }
70
+ if (tzmax < tmax)
71
+ tmax = tzmax;
72
+ if (tmin < t) {
73
+ t = tmin;
74
+ f = face;
75
+ }
76
+ }
77
+ if (t === Number.MAX_VALUE)
78
+ return null;
79
+ return { pos: this.pos.plus(this.dir.scaled(t)), face: f };
80
+ }
81
+ next() {
82
+ if (Math.min(Math.min(this.tMaxX, this.tMaxY), this.tMaxZ) > this.maxDistance) {
83
+ return null;
84
+ }
85
+ if (this.tMaxX < this.tMaxY) {
86
+ if (this.tMaxX < this.tMaxZ) {
87
+ this.block.x += this.stepX;
88
+ this.tMaxX += this.tDeltaX;
89
+ this.block.face = this.stepX > 0 ? BlockFace.WEST : BlockFace.EAST;
90
+ }
91
+ else {
92
+ this.block.z += this.stepZ;
93
+ this.tMaxZ += this.tDeltaZ;
94
+ this.block.face = this.stepZ > 0 ? BlockFace.NORTH : BlockFace.SOUTH;
95
+ }
96
+ }
97
+ else {
98
+ if (this.tMaxY < this.tMaxZ) {
99
+ this.block.y += this.stepY;
100
+ this.tMaxY += this.tDeltaY;
101
+ this.block.face = this.stepY > 0 ? BlockFace.BOTTOM : BlockFace.TOP;
102
+ }
103
+ else {
104
+ this.block.z += this.stepZ;
105
+ this.tMaxZ += this.tDeltaZ;
106
+ this.block.face = this.stepZ > 0 ? BlockFace.NORTH : BlockFace.SOUTH;
107
+ }
108
+ }
109
+ if (isNaN(this.block.x) || isNaN(this.block.y) || isNaN(this.block.z))
110
+ return null;
111
+ return this.block;
112
+ }
113
+ }
114
+ exports.RaycastIterator = RaycastIterator;
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@nxg-org/mineflayer-util-plugin",
3
+ "version": "1.0.0",
4
+ "description": "mineflayer utils for NextGEN mineflayer plugins.",
5
+ "keywords": [
6
+ "mineflayer",
7
+ "mineflayer-util"
8
+ ],
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/nxg-org/mineflayer-util-plugin.git"
12
+ },
13
+ "license": "GPL-3.0",
14
+ "author": "generel_schwerz",
15
+ "main": "lib/index.js",
16
+ "types": "lib/index.d.ts",
17
+ "scripts": {
18
+ "build": "npx tsc",
19
+ "prepublish": "npm run build"
20
+ },
21
+ "dependencies": {
22
+ "minecraft-data": "^2.97.0",
23
+ "mineflayer": "^3.11.2",
24
+ "mineflayer-pathfinder": "^1.8.0",
25
+ "prismarine-block": "^1.10.3",
26
+ "prismarine-item": "^1.11.1",
27
+ "vec3": "^0.1.7"
28
+ },
29
+ "devDependencies": {
30
+ "@types/node": "^16.11.11",
31
+ "typescript": "^4.5.2"
32
+ }
33
+ }
@@ -0,0 +1,19 @@
1
+ import type { Bot } from "mineflayer";
2
+ import type { Block } from "prismarine-block";
3
+ import { AABB } from "./calcs/aabb";
4
+ import type { Vec3 } from "vec3";
5
+
6
+ export class WorldFunctions {
7
+ constructor (private bot: Bot) {}
8
+
9
+
10
+ getBlockAABB(block: Block, height: number = 1) {
11
+ const {x, y, z} = block.position
12
+ return new AABB(x, y, z, x + 1, y + height, z + 1)
13
+ }
14
+
15
+ getBlockPosAABB(block: Vec3, height: number = 1) {
16
+ const {x, y, z} = block.floored()
17
+ return new AABB(x, y, z, x + 1, y + height, z + 1)
18
+ }
19
+ }
@@ -0,0 +1,218 @@
1
+ import { Vec3 } from "vec3";
2
+
3
+ export class AABB {
4
+ public minX: number;
5
+ public minY: number;
6
+ public minZ: number;
7
+ public maxX: number;
8
+ public maxY: number;
9
+ public maxZ: number;
10
+
11
+ constructor(x0: number, y0: number, z0: number, x1: number, y1: number, z1: number) {
12
+ this.minX = x0;
13
+ this.minY = y0;
14
+ this.minZ = z0;
15
+ this.maxX = x1;
16
+ this.maxY = y1;
17
+ this.maxZ = z1;
18
+ }
19
+
20
+ static fromVecs(min: Vec3, max: Vec3) {
21
+ return new AABB(min.x, min.y, min.z, max.x, max.y, max.z);
22
+ }
23
+
24
+ set(x0: number, y0: number, z0: number, x1: number, y1: number, z1: number) {
25
+ this.minX = x0;
26
+ this.minY = y0;
27
+ this.minZ = z0;
28
+ this.maxX = x1;
29
+ this.maxY = y1;
30
+ this.maxZ = z1;
31
+ }
32
+
33
+ clone() {
34
+ return new AABB(this.minX, this.minY, this.minZ, this.maxX, this.maxY, this.maxZ);
35
+ }
36
+
37
+ toArray() {
38
+ return [this.minX, this.minY, this.minZ, this.maxX, this.maxY, this.maxZ];
39
+ }
40
+
41
+ toMinAndMaxArrays() {
42
+ return { 0: [this.minX, this.minY, this.minZ], 1: [this.maxX, this.maxY, this.maxZ] };
43
+ }
44
+
45
+ toVecs() {
46
+ return { 0: new Vec3(this.minX, this.minY, this.minZ), 1: new Vec3(this.maxX, this.maxY, this.maxZ) };
47
+ }
48
+
49
+ floor() {
50
+ this.minX = Math.floor(this.minX);
51
+ this.minY = Math.floor(this.minY);
52
+ this.minZ = Math.floor(this.minZ);
53
+ this.maxX = Math.floor(this.maxX);
54
+ this.maxY = Math.floor(this.maxY);
55
+ this.maxZ = Math.floor(this.maxZ);
56
+ }
57
+
58
+ extend(dx: number, dy: number, dz: number) {
59
+ if (dx < 0) this.minX += dx;
60
+ else this.maxX += dx;
61
+
62
+ if (dy < 0) this.minY += dy;
63
+ else this.maxY += dy;
64
+
65
+ if (dz < 0) this.minZ += dz;
66
+ else this.maxZ += dz;
67
+
68
+ return this;
69
+ }
70
+
71
+ contract(x: number, y: number, z: number) {
72
+ this.minX += x;
73
+ this.minY += y;
74
+ this.minZ += z;
75
+ this.maxX -= x;
76
+ this.maxY -= y;
77
+ this.maxZ -= z;
78
+ return this;
79
+ }
80
+
81
+ expand(x: number, y: number, z: number) {
82
+ this.minX -= x;
83
+ this.minY -= y;
84
+ this.minZ -= z;
85
+ this.maxX += x;
86
+ this.maxY += y;
87
+ this.maxZ += z;
88
+ return this;
89
+ }
90
+
91
+ offset(x: number, y: number, z: number) {
92
+ this.minX += x;
93
+ this.minY += y;
94
+ this.minZ += z;
95
+ this.maxX += x;
96
+ this.maxY += y;
97
+ this.maxZ += z;
98
+ return this;
99
+ }
100
+
101
+ computeOffsetX(other: AABB, offsetX: number) {
102
+ if (other.maxY > this.minY && other.minY < this.maxY && other.maxZ > this.minZ && other.minZ < this.maxZ) {
103
+ if (offsetX > 0.0 && other.maxX <= this.minX) {
104
+ offsetX = Math.min(this.minX - other.maxX, offsetX);
105
+ } else if (offsetX < 0.0 && other.minX >= this.maxX) {
106
+ offsetX = Math.max(this.maxX - other.minX, offsetX);
107
+ }
108
+ }
109
+ return offsetX;
110
+ }
111
+
112
+ computeOffsetY(other: AABB, offsetY: number) {
113
+ if (other.maxX > this.minX && other.minX < this.maxX && other.maxZ > this.minZ && other.minZ < this.maxZ) {
114
+ if (offsetY > 0.0 && other.maxY <= this.minY) {
115
+ offsetY = Math.min(this.minY - other.maxY, offsetY);
116
+ } else if (offsetY < 0.0 && other.minY >= this.maxY) {
117
+ offsetY = Math.max(this.maxY - other.minY, offsetY);
118
+ }
119
+ }
120
+ return offsetY;
121
+ }
122
+
123
+ computeOffsetZ(other: AABB, offsetZ: number) {
124
+ if (other.maxX > this.minX && other.minX < this.maxX && other.maxY > this.minY && other.minY < this.maxY) {
125
+ if (offsetZ > 0.0 && other.maxZ <= this.minZ) {
126
+ offsetZ = Math.min(this.minZ - other.maxZ, offsetZ);
127
+ } else if (offsetZ < 0.0 && other.minZ >= this.maxZ) {
128
+ offsetZ = Math.max(this.maxZ - other.minZ, offsetZ);
129
+ }
130
+ }
131
+ return offsetZ;
132
+ }
133
+
134
+ intersects(other: AABB) {
135
+ return (
136
+ this.minX < other.maxX &&
137
+ this.maxX > other.minX &&
138
+ this.minY < other.maxY &&
139
+ this.maxY > other.minY &&
140
+ this.minZ < other.maxZ &&
141
+ this.maxZ > other.minZ
142
+ );
143
+ }
144
+
145
+ intersectsRay(origin: Vec3, direction: Vec3) {
146
+ const d = this.distanceFromRay(origin, direction);
147
+ if (d === Infinity) {
148
+ return null;
149
+ } else {
150
+ return new Vec3(origin.x + direction.x * d, origin.y + direction.y * d, origin.z + direction.z * d);
151
+ }
152
+ }
153
+
154
+ distanceFromRay(origin: Vec3, direction: Vec3) {
155
+ const ro = origin.toArray();
156
+ const rd = direction.normalize().toArray();
157
+ const aabb = this.toMinAndMaxArrays();
158
+ const dims = ro.length; // will change later.
159
+ let lo = -Infinity;
160
+ let hi = +Infinity;
161
+ // let test = origin.clone()
162
+
163
+ for (let i = 0; i < dims; i++) {
164
+ let dimLo = (aabb[0][i] - ro[i]) / rd[i];
165
+ let dimHi = (aabb[1][i] - ro[i]) / rd[i];
166
+
167
+ if (dimLo > dimHi) {
168
+ let tmp = dimLo;
169
+ dimLo = dimHi;
170
+ dimHi = tmp;
171
+ }
172
+
173
+ // let num;
174
+ // switch (i) {
175
+ // case 0:
176
+ // num = "x"
177
+ // break;
178
+ // case 1:
179
+ // num = "y"
180
+ // break;
181
+ // case 2:
182
+ // num = "z"
183
+ // break;
184
+ // }
185
+ // console.log(num, aabb[0][i], aabb[1][i], ro[i], "highest overall:", lo, hi )
186
+ if (dimHi < lo || dimLo > hi) {
187
+ console.log("fuck", dimHi < lo, dimLo > hi);
188
+ return Infinity;
189
+ }
190
+
191
+ if (dimLo > lo) lo = dimLo;
192
+ if (dimHi < hi) hi = dimHi;
193
+ }
194
+
195
+ return lo > hi ? Infinity : lo;
196
+ }
197
+
198
+ equals(other: AABB): boolean {
199
+ return (
200
+ this.minX === other.minX &&
201
+ this.minY === other.minY &&
202
+ this.minZ === other.minZ &&
203
+ this.maxX === other.maxX &&
204
+ this.maxY === other.maxY &&
205
+ this.maxZ === other.maxZ
206
+ );
207
+ }
208
+
209
+ distanceTo(pos: Vec3, heightOffset: number = 0): number {
210
+ const { x, y, z } = pos.offset(0, heightOffset, 0);
211
+ let dx = Math.max(this.minX - x, 0, x - this.maxX);
212
+ let dy = Math.max(this.minY - y, 0, y - this.maxY);
213
+ let dz = Math.max(this.minZ - z, 0, z - this.maxZ);
214
+ return Math.sqrt(dx * dx + dy * dy + dz * dz);
215
+ }
216
+ }
217
+
218
+ export default AABB;
@@ -0,0 +1,189 @@
1
+ import type { Bot, EquipmentDestination } from "mineflayer";
2
+ import { Vec3 } from "vec3";
3
+ import { promisify } from "util";
4
+ import type { Block } from "prismarine-block";
5
+ const sleep = promisify(setTimeout);
6
+
7
+ export class CommonSense {
8
+ public autoRespond: boolean = false;
9
+ public isFalling: boolean = false;
10
+ public isOnFire: boolean = false;
11
+ public checkForFalling: boolean = true;
12
+ public checkForFire: boolean = true;
13
+ public useOffHand: boolean = true;
14
+ public requipLastItem: boolean = false;
15
+ public puttingOutFire: boolean = false;
16
+ public MLGing: boolean = false;
17
+ constructor(public bot: Bot) {
18
+ this.bot.on("physicsTick", this.isFallingCheckEasy.bind(this));
19
+ this.bot._client.on("entity_metadata", this.onMetadataFireCheck.bind(this));
20
+ this.bot._client.on("entity_status", this.onStatusFireCheck.bind(this));
21
+ // this.bot.on("physicsTick", this.onPhysicsTickFireCheck.bind(this));
22
+ //TODO: Move this to bot movement.
23
+ }
24
+
25
+ // async onPhysicsTickFireCheck() {
26
+ // if ((this.bot.entity.metadata[0] as any) === 1) {
27
+ // this.isOnFire = true;
28
+ // while (!this.bot.entity.onGround) await sleep(0);
29
+ // if (!this.puttingOutFire && this.autoRespond) this.putOutFire();
30
+ // } else {
31
+ // this.isOnFire = false
32
+ // }
33
+ // }
34
+
35
+ async onMetadataFireCheck(packet: any) {
36
+ if (!this.checkForFire) return;
37
+ if (!packet.entityId) return;
38
+ const entity = this.bot.entities[packet.entityId];
39
+ if (!entity || entity !== this.bot.entity) return;
40
+ // if ((entity.metadata[0] as any).value !== 1) {
41
+ const wantedKey = (packet.metadata as any[]).findIndex((md) => md.key === 0);
42
+ if (wantedKey === -1) return;
43
+ if (packet.metadata[wantedKey]?.value !== 1) {
44
+ this.isOnFire = false;
45
+ return;
46
+ }
47
+ // }
48
+
49
+ this.isOnFire = true;
50
+ while (!this.bot.entity.onGround) await this.bot.waitForTicks(1);
51
+ if (!this.puttingOutFire && this.autoRespond) this.putOutFire();
52
+ }
53
+
54
+ async onStatusFireCheck(packet: any) {
55
+ if (!this.checkForFire) return;
56
+ if (!packet.entityId) return;
57
+ const entity = this.bot.entities[packet.entityId];
58
+ if (!entity || entity !== this.bot.entity) return;
59
+ if (!packet.entityStatus || packet.entityStatus !== 37) {
60
+ this.isOnFire = false;
61
+ return;
62
+ }
63
+
64
+ this.isOnFire = true;
65
+ while (!this.bot.entity.onGround) await sleep(0);
66
+ if (!this.puttingOutFire && this.autoRespond) this.putOutFire();
67
+ }
68
+
69
+ async putOutFire() {
70
+ if (this.puttingOutFire) return true;
71
+ this.puttingOutFire = true;
72
+ const water = this.bot.util.inv.getAllItemsExceptCurrent("off-hand").find((item) => item?.name.includes("water_bucket"));
73
+ const holdingItem = this.bot.util.inv.getHandWithItem(this.useOffHand)?.name.includes("water_bucket");
74
+ if (!water && !holdingItem) {
75
+ this.puttingOutFire = false;
76
+ return false;
77
+ } else if (!holdingItem && water) await this.bot.util.inv.customEquip(water, "off-hand");
78
+
79
+ if (this.bot.util.inv.getHandWithItem(this.useOffHand)?.name.includes("water_bucket")) {
80
+ const nearbyBlock = this.bot.findBlock({ matching: (block) => block?.name === "fire", maxDistance: 2 });
81
+
82
+ if (nearbyBlock) {
83
+ await this.bot.dig(nearbyBlock, true);
84
+ await this.bot.util.move.forceLookAt(nearbyBlock.position.offset(0, -1, 0));
85
+ } else {
86
+ await this.bot.util.move.forceLook(this.bot.entity.yaw, -90);
87
+ }
88
+ // while (!this.bot.entity.isCollidedVertically) await this.bot.waitForTicks(1);
89
+ this.bot.activateItem(this.useOffHand);
90
+
91
+ await this.pickUpWater(nearbyBlock);
92
+ this.puttingOutFire = false;
93
+ return true;
94
+ } else {
95
+ this.puttingOutFire = false;
96
+ return false;
97
+ }
98
+ }
99
+
100
+ async pickUpWater(nearbyBlock: Block | null = null, maxDistance: number = 2, immediate: boolean = false) {
101
+ if (!immediate) await this.bot.waitForTicks(3);
102
+ const block = this.bot.findBlock({
103
+ point: nearbyBlock?.position ?? this.bot.entity.position,
104
+ matching: (block) => (block.type === 8 || block.type === 9) && block.metadata === 0,
105
+ //@ts-expect-error
106
+ useExtraInfo: (block: Block) => {
107
+ return this.bot.util.world.getBlockAABB(block).distanceTo(this.bot.entity.position, 1.62) < 4;
108
+ },
109
+ maxDistance: maxDistance,
110
+ });
111
+ if (block) {
112
+ this.bot.util.move.forceLookAt(block.position.offset(0.5, 0.5, 0.5), true);
113
+ this.bot.activateItem(this.useOffHand);
114
+ } else {
115
+ console.log("didn't get block. fuck.");
116
+ }
117
+ }
118
+ async isFallingCheckEasy() {
119
+ if (!this.checkForFalling) return;
120
+ if (this.bot.entity.velocity.y >= -0.6) {
121
+ this.isFalling = false;
122
+ return;
123
+ }
124
+ this.isFalling = true;
125
+ if (!this.MLGing && this.autoRespond) {
126
+ await this.waterBucket();
127
+ }
128
+ }
129
+
130
+ private findBlockForWaterPlacement() {
131
+ const pos = this.bot.entity.position.offset(this.bot.entity.velocity.x, 0, this.bot.entity.velocity.z);
132
+ const aabb = this.bot.util.entity.getEntityAABB({
133
+ position: pos,
134
+ height: this.bot.entity.height,
135
+ width: 0.3,
136
+ });
137
+ const spacing = { x0: aabb.minX, z0: aabb.minZ, x1: aabb.maxX, z1: aabb.maxZ };
138
+ const floored = { x0: Math.floor(spacing.x0), z0: Math.floor(spacing.z0), x1: Math.floor(spacing.x1), z1: Math.floor(spacing.z1) };
139
+ let blocks: Block[] = [];
140
+ const posY = this.bot.entity.position.clone().floored().y;
141
+ loop1: for (let i = floored.x0; i <= floored.x1; i++) {
142
+ loop2: for (let j = floored.z0; j <= floored.z1; j++) {
143
+ loop3: for (let k = posY; k > 0; k--) {
144
+ const block = this.bot.blockAt(new Vec3(i, k, j));
145
+ if (!!block && block.type !== 0) {
146
+ blocks.push(block);
147
+ break loop3;
148
+ }
149
+ }
150
+ }
151
+ }
152
+
153
+ const maxY = Math.max(...blocks.map((b) => b.position.y));
154
+ blocks = blocks.filter((b) => b.position.y === maxY);
155
+
156
+ const block = blocks.sort(
157
+ (a, b) => this.bot.util.world.getBlockAABB(b).distanceTo(pos) - this.bot.util.world.getBlockAABB(a).distanceTo(pos)
158
+ )[0];
159
+ // console.log(block.position, this.bot.entity.position, this.bot.entity.position.distanceTo(block.position).toFixed(2));
160
+ return block;
161
+ }
162
+
163
+ async waterBucket() {
164
+ if (this.MLGing) return true;
165
+ this.MLGing = true;
166
+ const water = this.bot.util.inv.getAllItemsExceptCurrent("off-hand").find((item) => item?.name.includes("water_bucket"));
167
+ const holdingItem = this.bot.util.inv.getHandWithItem(true)?.name.includes("water_bucket");
168
+ if (!water && !holdingItem) {
169
+ this.MLGing = false;
170
+ return false;
171
+ } else if (!holdingItem && water) await this.bot.util.inv.customEquip(water, "off-hand");
172
+
173
+ for (let i = 0; i < 120; i++) {
174
+ const landingBlock = this.findBlockForWaterPlacement();
175
+ if (landingBlock) {
176
+ await this.bot.util.move.forceLookAt(landingBlock.position.offset(0.5, 0.5, 0.5), true);
177
+ }
178
+
179
+ if (this.bot.entity.position.y <= (landingBlock?.position.y ?? 0) + 3) {
180
+ this.bot.activateItem(this.useOffHand);
181
+ break;
182
+ }
183
+ await this.bot.waitForTicks(1);
184
+ }
185
+ await this.pickUpWater(null, 2);
186
+ this.MLGing = false;
187
+ return true;
188
+ }
189
+ }
@@ -0,0 +1,90 @@
1
+ import type { Bot, EquipmentDestination } from "mineflayer";
2
+ import type { Item } from "prismarine-item";
3
+ import assert from "assert";
4
+ import { promisify } from "util";
5
+ const sleep = promisify(setTimeout);
6
+
7
+ const QUICK_BAR_COUNT = 9;
8
+ const QUICK_BAR_START = 36;
9
+
10
+ let nextQuickBarSlot = 0;
11
+
12
+ //lazy. will fix this later.
13
+
14
+ export class CustomInventoryFunctions {
15
+ armorSlots = {
16
+ head: 5,
17
+ torso: 6,
18
+ legs: 7,
19
+ feet: 8,
20
+ } as any;
21
+
22
+ constructor(private bot: Bot) {
23
+ if (!bot.supportFeature("doesntHaveOffHandSlot")) {
24
+ this.armorSlots["off-hand"] = 45;
25
+ }
26
+ }
27
+
28
+ async equip(item: Item, destination: EquipmentDestination) {
29
+ if (item == null || typeof item !== "object") {
30
+ throw new Error("Invalid item object in equip (item is null or typeof item is not object)");
31
+ }
32
+ if (!destination || destination === null) {
33
+ destination = "hand";
34
+ }
35
+ const sourceSlot = item.slot;
36
+ let destSlot = this.getDestSlot(destination);
37
+
38
+ if (sourceSlot === destSlot) {
39
+ // don't need to do anything
40
+ return;
41
+ }
42
+
43
+ if (destination !== "hand") {
44
+ await this.bot.moveSlotItem(sourceSlot, destSlot);
45
+ return;
46
+ }
47
+
48
+ if (
49
+ destSlot >= QUICK_BAR_START &&
50
+ destSlot < QUICK_BAR_START + QUICK_BAR_COUNT &&
51
+ sourceSlot >= QUICK_BAR_START &&
52
+ sourceSlot < QUICK_BAR_START + QUICK_BAR_COUNT
53
+ ) {
54
+ // all we have to do is change the quick bar selection
55
+ this.bot.setQuickBarSlot(sourceSlot - QUICK_BAR_START);
56
+ return;
57
+ }
58
+
59
+ // find an empty slot on the quick bar to put the source item in
60
+ destSlot = this.bot.inventory.firstEmptySlotRange(QUICK_BAR_START, QUICK_BAR_START + QUICK_BAR_COUNT);
61
+ if (destSlot == null) {
62
+ // LRU cache for the quick bar items
63
+ destSlot = QUICK_BAR_START + nextQuickBarSlot;
64
+ nextQuickBarSlot = (nextQuickBarSlot + 1) % QUICK_BAR_COUNT;
65
+ }
66
+ this.setQuickBarSlot(destSlot - QUICK_BAR_START);
67
+ await this.bot.moveSlotItem(sourceSlot, destSlot);
68
+ }
69
+
70
+ setQuickBarSlot(slot: number) {
71
+ assert.ok(slot >= 0);
72
+ assert.ok(slot < 9);
73
+ if (this.bot.quickBarSlot === slot) return;
74
+ this.bot.quickBarSlot = slot;
75
+ this.bot._client.write("held_item_slot", {
76
+ slotId: slot,
77
+ });
78
+ this.bot.updateHeldItem();
79
+ }
80
+
81
+ getDestSlot(destination: EquipmentDestination) {
82
+ if (destination === "hand") {
83
+ return QUICK_BAR_START + this.bot.quickBarSlot;
84
+ } else {
85
+ const destSlot = this.armorSlots[destination];
86
+ assert.ok(destSlot != null, `invalid destination: ${destination}`);
87
+ return destSlot;
88
+ }
89
+ }
90
+ }