1
- const mineflayer = require ( 'mineflayer' ) ;
2
- const { pathfinder, Movements, goals } = require ( 'mineflayer-pathfinder' ) ;
3
- const GoalNear = goals . GoalNear ;
4
- const { Vec3 } = require ( 'vec3' ) ;
1
+ const mineflayer = require ( 'mineflayer' )
2
+ const collectBlockPlugin = require ( 'mineflayer-collectblock' ) . plugin
3
+ const { Vec3 } = require ( 'vec3' )
5
4
6
5
const bot = mineflayer . createBot ( {
7
- host : 'localhost' ,
8
- port : 42577 ,
9
- username : 'lumberjack_Bot'
6
+ host : process . argv [ 2 ] ,
7
+ port : process . argv [ 3 ] ,
8
+ username : process . argv [ 4 ] || 'lumberjack_Bot' ,
9
+ password : process . argv [ 5 ]
10
10
} )
11
11
12
- bot . loadPlugin ( pathfinder ) ;
12
+ bot . loadPlugin ( collectBlockPlugin ) ;
13
13
14
- const FARM_POINT_1 = new Vec3 ( 372 , 4 , 153 )
15
- const FARM_POINT_2 = new Vec3 ( 394 , 14 , 191 )
16
- const DEPOSIT_CHEST = new Vec3 ( 362 , 5 , 146 )
17
- const LOG_TYPES = [ ]
14
+ // Tree farm bounds
15
+ const FARM_POINT_1 = new Vec3 ( 265 , 76 , 283 )
16
+ const FARM_POINT_2 = new Vec3 ( 239 , 84 , 305 )
17
+ const FARM_MIN = FARM_POINT_1 . min ( FARM_POINT_2 )
18
+ const FARM_MAX = FARM_POINT_1 . max ( FARM_POINT_2 )
18
19
20
+ // Load deposit chests
19
21
bot . once ( 'spawn' , ( ) => {
20
- loadLogTypes ( )
21
- gatherWood ( )
22
+ bot . collectBlock . chestLocations . push ( new Vec3 ( 244 , 75 , 274 ) )
23
+ bot . collectBlock . chestLocations . push ( new Vec3 ( 242 , 75 , 274 ) )
24
+ bot . collectBlock . chestLocations . push ( new Vec3 ( 242 , 75 , 271 ) )
25
+ bot . collectBlock . chestLocations . push ( new Vec3 ( 243 , 75 , 271 ) )
26
+ bot . collectBlock . chestLocations . push ( new Vec3 ( 244 , 77 , 274 ) )
27
+ bot . collectBlock . chestLocations . push ( new Vec3 ( 242 , 77 , 274 ) )
28
+ bot . collectBlock . chestLocations . push ( new Vec3 ( 242 , 77 , 271 ) )
29
+ bot . collectBlock . chestLocations . push ( new Vec3 ( 243 , 77 , 271 ) )
22
30
} )
23
31
24
- function loadLogTypes ( ) {
25
- const mcData = require ( 'minecraft-data' )
26
- LOG_TYPES . push ( mcData . blocksByName . oak_log . id )
27
- LOG_TYPES . push ( mcData . blocksByName . spruce_log . id )
28
- LOG_TYPES . push ( mcData . blocksByName . birch_log . id )
29
- }
32
+ // Load axe retrieval chests
33
+ bot . once ( 'spawn' , ( ) => {
34
+ bot . tool . chestLocations . push ( new Vec3 ( 254 , 76 , 282 ) )
35
+ } )
30
36
31
- function gatherWood ( ) {
32
- const block = findWood ( block )
33
- if ( ! block ) {
34
- setTimeout ( gatherWood , 5000 )
35
- return
37
+ // Load Minecraft Data
38
+ let mcData
39
+ bot . once ( 'spawn' , ( ) => {
40
+ mcData = require ( 'minecraft-data' ) ( bot . version )
41
+ } )
42
+
43
+ // Load log types
44
+ let logTypes
45
+ bot . once ( 'spawn' , ( ) => {
46
+ logTypes = buildIDList ( [
47
+ // Before 1.13 logs were called "wood"
48
+ 'oak_wood' , 'birch_wood' , 'jungle_wood' , 'spruce_wood' , 'acacia_wood' , 'dark_oak_wood' ,
49
+
50
+ // 1.13 and later, logs are called logs
51
+ 'oak_log' , 'spruce_log' , 'birch_log' , 'jungle_log' , 'acacia_log' , 'dark_oak_log' ,
52
+
53
+ // In 1.16 and later, we have nether trees, too!
54
+ 'crimson_stem' , 'warped_stem'
55
+ ] )
56
+ } )
57
+
58
+ // Load dirt types
59
+ let dirtTypes
60
+ bot . once ( 'spawn' , ( ) => {
61
+ dirtTypes = buildIDList ( [
62
+ // After 1.13, "grass" was renamed to "grass_block", so we need to check for both
63
+ 'dirt' , 'podzol' , 'grass' , 'grass_block'
64
+ ] )
65
+ } )
66
+
67
+ // Create a list of block IDs from a list of block names
68
+ function buildIDList ( names ) {
69
+ const types = [ ]
70
+ for ( const name of names ) {
71
+ const type = mcData . blocksByName [ name ]
72
+ if ( type ) logTypes . push ( type . id )
36
73
}
37
74
38
- chopTree ( block , ( ) => {
75
+ return types
76
+ }
39
77
40
- } )
78
+ // Checks if the block is a log
79
+ function isLog ( block ) {
80
+ return logTypes . includes ( block . type )
41
81
}
42
82
43
- function findWood ( ) {
44
- for ( let x = FARM_POINT_1 . x ; x <= FARM_POINT_2 . x ; x ++ ) {
45
- for ( let z = FARM_POINT_1 . z ; z <= FARM_POINT_2 . z ; z ++ ) {
46
- for ( let y = FARM_POINT_1 . y ; y <= FARM_POINT_2 . y ; y ++ ) {
47
- const block = bot . blockAt ( new Vec3 ( x , y , z ) )
48
- if ( ! block ) continue
83
+ // Checks if the block is dirt or grass
84
+ function isDirt ( block ) {
85
+ return dirtTypes . includes ( block . type )
86
+ }
87
+
88
+ // Create listeners for tree locations and collect existing trees
89
+ bot . once ( 'spawn' , ( ) => {
90
+
91
+ // Iterate over all blocks along the bottom of the farm
92
+ for ( let x = FARM_MIN . x ; x <= FARM_MAX . x ; x ++ ) {
93
+ for ( let z = FARM_MIN . z ; z <= FARM_MIN . z ; z ++ ) {
94
+ let pos = new Vec3 ( x , FARM_MIN . y , z )
95
+
96
+ // Only look for dirt blocks, since that's what our trees grow on
97
+ const block = bot . blockAt ( pos )
98
+ if ( ! isDirt ( block ) ) continue
99
+
100
+ // If we found a tree spot, create an event listener for the block above
101
+ pos = pos . offset ( 0 , 1 , 0 )
102
+ bot . on ( `blockUpdate:${ pos } ` , ( oldBlock , newBlock ) => collectTree ( newBlock ) )
49
103
50
- if ( LOG_TYPES . indexOf ( block . type ) > - 1 )
51
- return block
52
- }
104
+ // Try and collect the tree if there is one
105
+ collectTree ( block )
53
106
}
54
107
}
108
+ } )
109
+
110
+ let replantLocations = [ ]
111
+
112
+ // Get all logs in the tree and collect them
113
+ function collectTree ( root ) {
114
+ if ( ! isLog ( root ) ) return
115
+ const logs = bot . collectBlock . findFromVein ( newBlock )
116
+ bot . collectBlock . collect ( logs , { append : true } , logError )
117
+
118
+ // Make note that the location needs to be replanted when finished
119
+ replaceLocations . push ( block . position )
55
120
}
56
121
57
- function chopTree ( block , cb ) {
58
- breakBlock ( block , cb )
122
+ // Log any errors we receive to the console, and declare it in chat.
123
+ function logError ( err ) {
124
+ if ( err ) {
125
+ bot . chat ( 'An error has occurred.' )
126
+ console . log ( err )
127
+ }
59
128
}
60
129
61
- function breakBlock ( block , cb ) {
62
- equipTool ( block , ( ) => {
63
- bot . dig ( block , cb )
64
- } )
130
+ // Collect any item that drops in the tree farm
131
+ bot . on ( 'itemDrop' , ( entity ) => {
132
+ if ( isInBounds ( entity . position ) ) {
133
+ bot . collectBlock . collect ( logs , { append : true } , logError )
134
+ }
135
+ } )
136
+
137
+ // Checks if the given position is within the tree farm or not.
138
+ function isInBounds ( pos ) {
139
+ return pos . x >= FARM_MIN . x && pos . y >= FARM_MIN . y && pos . z >= FARM_MIN . z &&
140
+ pos . x <= FARM_MAX . x && pos . y <= FARM_MAX . y && pos . z <= FARM_MAX . z
65
141
}
66
142
67
- function equipTool ( block , cb ) {
68
- const tool = bot . pathfinder . bestHarvestTool ( block )
69
- if ( ! tool ) {
143
+ // Replant any saplings we have
144
+ bot . on ( 'collectBlock_finished' , ( ) => {
145
+ replantSaplings ( )
146
+ } )
147
+
148
+ // Replant as many saplings as we can
149
+ function replantSaplings ( cb ) {
150
+ // Check if we have any locations left that are missing saplings
151
+ if ( replantLocations . length === 0 ) {
70
152
cb ( )
71
153
return
72
154
}
73
155
74
- bot . equip ( tool , 'hand' , cb )
156
+ // Find a sapling in the bot's inventory
157
+ const sapling = bot . inventory . items ( ) . find ( item => item . name . includes ( 'sapling' ) )
158
+ if ( ! sapling ) {
159
+ cb ( ) // Return early if we don't have any more
160
+ return
161
+ }
162
+
163
+ // Move to the next sapling location and replant it
164
+ const location = replantLocations . pop ( )
165
+ bot . pathfinder . goto ( location , ( err ) => {
166
+
167
+ // If we are interrupted because the goal changed because of
168
+ // collectBlock, we can do nothing and try to finish sometime later.
169
+ if ( err . name === 'GoalChanged' ) return
170
+
171
+ bot . equip ( sapling , 'hand' , ( ) => {
172
+ const referenceBlock = bot . blockAt ( location . offset ( 0 , - 1 , 0 ) )
173
+ bot . placeBlock ( referenceBlock , new Vec3 ( 0 , 1 , 0 ) , ( ) => replantSaplings ( cb ) )
174
+ } )
175
+ } )
75
176
}
0 commit comments