-
Notifications
You must be signed in to change notification settings - Fork 27
/
avoidBedrock.js
113 lines (95 loc) · 3.08 KB
/
avoidBedrock.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
const aStar = require('a-star');
module.exports = init;
const MONITOR_INTERVAL = 40;
const WATER_THRESHOLD = 20;
const DEFAULT_TIMEOUT = 10 * 1000; // 10 seconds
const DEFAULT_END_RADIUS = 0.1;
// if the distance is more than this number, navigator will opt to simply
// head in the correct direction and recalculate upon getting closer
const TOO_FAR_THRESHOLD = 150;
function init() {
return inject;
}
function inject(bot) {
bot.navigate2 = {};
bot.navigate2.findPathSync = findPathSync;
bot.navigate2.blocksToAvoid = {
7: true, // bedrock
};
function findPathSync(end, params) {
params = params || {};
end = end.floored();
const timeout = params.timeout == null ? DEFAULT_TIMEOUT : params.timeout;
const endRadius = params.endRadius == null ? DEFAULT_END_RADIUS : params.endRadius;
const tooFarThreshold = params.tooFarThreshold == null ? TOO_FAR_THRESHOLD : params.tooFarThreshold;
let actualIsEnd = params.isEnd || createIsEndWithRadius(end, endRadius);
const heuristic = createHeuristicFn(end);
const start = bot.entity.position.floored();
console.log(start);
let tooFar = false;
if (start.distanceTo(end) > tooFarThreshold) {
// Too far to calculate reliably. Return 'tooFar' and a path to walk
// in the general direction of end.
actualIsEnd = function(node) {
// let's just go 100 meters
return start.distanceTo(node.point) >= 100;
};
tooFar = true;
}
// search
const results = aStar({
start: new Node(start, 0),
isEnd: actualIsEnd,
neighbor: getNeighbors,
distance: distanceFunc,
heuristic: heuristic,
timeout: timeout,
});
results.status = tooFar ? 'tooFar' : results.status;
results.path = results.path.map(nodeCenterOffset);
return results;
}
function getNeighbors(node)
{
const p=node.point;
const result=[];
if(risSafe(p,0,-1,0)) result.push(p.offset(0,-1,0));
if(risSafe(p,0,2,0)) result.push(p.offset(0,1,0));
if(risSafe(p,1,0,0) && risSafe(p,1,1,0)) result.push(p.offset(1,0,0));
if(risSafe(p,-1,0,0) && risSafe(p,-1,1,0)) result.push(p.offset(-1,0,0));
if(risSafe(p,0,0,1) && risSafe(p,0,1,1)) result.push(p.offset(0,0,1));
if(risSafe(p,0,0,-1) && risSafe(p,0,1,-1)) result.push(p.offset(0,0,-1));
return result.map(function(point) {return new Node(point);});
}
function risSafe(p,x,y,z)
{
return isSafe(bot.blockAt(p.offset(x,y,z)))
}
function isSafe(block) {
return !bot.navigate2.blocksToAvoid[block.type];
}
}
function createIsEndWithRadius(end, radius) {
return function(node) {
return node.point.distanceTo(end) <= radius;
};
}
function distanceFunc(nodeA, nodeB) {
return nodeA.point.distanceTo(nodeB.point);
}
function nodeCenterOffset(node) {
return node.point.offset(0.5, 0, 0.5);
}
function Node(point) {
this.point = point;
}
Node.prototype.toString = function() {
// must declare a toString so that A* works.
return this.point.toString();
};
function createHeuristicFn(end) {
return function(node) {
return node.point.distanceTo(end);
};
}
function noop() {}