@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.
- package/LICENSE +674 -0
- package/lib/WorldFunctions.d.ts +10 -0
- package/lib/WorldFunctions.js +18 -0
- package/lib/calcs/aabb.d.ts +36 -0
- package/lib/calcs/aabb.js +194 -0
- package/lib/commonSense.d.ts +22 -0
- package/lib/commonSense.js +220 -0
- package/lib/customImplementations/inventory.d.ts +10 -0
- package/lib/customImplementations/inventory.js +95 -0
- package/lib/entityFunctions.d.ts +36 -0
- package/lib/entityFunctions.js +78 -0
- package/lib/filterFunctions.d.ts +23 -0
- package/lib/filterFunctions.js +45 -0
- package/lib/index.d.ts +27 -0
- package/lib/index.js +7 -0
- package/lib/inventoryFunctions.d.ts +45 -0
- package/lib/inventoryFunctions.js +208 -0
- package/lib/mathUtil.d.ts +23 -0
- package/lib/mathUtil.js +49 -0
- package/lib/movementFunctions.d.ts +43 -0
- package/lib/movementFunctions.js +109 -0
- package/lib/predictiveFunctions.d.ts +25 -0
- package/lib/predictiveFunctions.js +172 -0
- package/lib/utilFunctions.d.ts +50 -0
- package/lib/utilFunctions.js +140 -0
- package/lib/worldRelated/predictiveWorld.d.ts +41 -0
- package/lib/worldRelated/predictiveWorld.js +108 -0
- package/lib/worldRelated/raycastIterator.d.ts +45 -0
- package/lib/worldRelated/raycastIterator.js +114 -0
- package/package.json +33 -0
- package/src/WorldFunctions.ts +19 -0
- package/src/calcs/aabb.ts +218 -0
- package/src/commonSense.ts +189 -0
- package/src/customImplementations/inventory.ts +90 -0
- package/src/entityFunctions.ts +71 -0
- package/src/filterFunctions.ts +54 -0
- package/src/index.ts +29 -0
- package/src/inventoryFunctions.ts +187 -0
- package/src/mathUtil.ts +56 -0
- package/src/movementFunctions.ts +116 -0
- package/src/predictiveFunctions.ts +187 -0
- package/src/utilFunctions.ts +152 -0
- package/src/worldRelated/predictiveWorld.ts +109 -0
- package/src/worldRelated/raycastIterator.ts +136 -0
- 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
|
+
}
|