prismarine-world 3.4.0 → 3.6.1

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.
@@ -0,0 +1,14 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: npm
4
+ directory: "/"
5
+ schedule:
6
+ interval: daily
7
+ open-pull-requests-limit: 10
8
+ ignore:
9
+ - dependency-name: event-promise
10
+ versions:
11
+ - ">= 1.a, < 2"
12
+ - dependency-name: mkdirp
13
+ versions:
14
+ - ">= 1.a, < 2"
package/docs/API.md CHANGED
@@ -179,3 +179,20 @@ It steps exactly 1 block at a time, returning the block coordinates and the face
179
179
  #### next()
180
180
 
181
181
  return null or the next position (Vec3)
182
+
183
+ ### SpiralIterator2d (pos, maxDistance)
184
+
185
+ `pos` is Vec3
186
+
187
+ `maxDistance` is number
188
+
189
+ Iterates outwards along x and z axis in a cubic spiral. First position returned is the starting position. Every step is 1 step away form the previous and next point.
190
+
191
+ #### next()
192
+
193
+ return null or the next position (Vec3)
194
+
195
+ #### NUMBER_OF_POINTS
196
+
197
+ Number of points the iterator will return.
198
+
package/docs/HISTORY.md CHANGED
@@ -1,5 +1,17 @@
1
1
  ## History
2
2
 
3
+ ### 3.6.1
4
+
5
+ * Update mcdata
6
+
7
+ ### 3.6.0
8
+
9
+ * Added match while check intersect (@sefirosweb)
10
+
11
+ ### 3.5.0
12
+
13
+ * fix getBlock not setting the position of the block
14
+
3
15
  ### 3.4.0
4
16
 
5
17
  * add block update events
@@ -1,12 +1,70 @@
1
1
  const Vec3 = require('vec3').Vec3
2
- const { OctahedronIterator } = require('../index').iterators
2
+ const { ManhattanIterator, SpiralIterator2d, OctahedronIterator } = require('../index').iterators
3
3
 
4
- const iterator = new OctahedronIterator(new Vec3(0, 0, 0), 5)
4
+ console.info('Octahedron Iterator 3D:\n' + iterate3d(new OctahedronIterator(new Vec3(0, 0, 0), 2)))
5
+ console.info('ManhattanIterator Iterator:\n' + iterate2d(new ManhattanIterator(0, 0, 5)))
6
+ console.info('SpiralIterator2d Iterator:\n' + iterate2d(new SpiralIterator2d(new Vec3(0, 0, 0), 4)))
5
7
 
6
- while (true) {
7
- const n = iterator.next()
8
- if (n === null) {
9
- break
8
+ function iterate3d (iter) {
9
+ let n = iter.next()
10
+ const result = []
11
+ const size = 3
12
+ let counter = 0
13
+ for (let x = 0; x < size * 2; x++) {
14
+ for (let y = 0; y < size * 2; y++) {
15
+ if (!result[x]) result[x] = []
16
+ for (let z = 0; z < size * 2; z++) {
17
+ if (!result[x][y]) result[x][y] = []
18
+ result[x][y][z] = ' '
19
+ }
20
+ }
10
21
  }
11
- console.log(n)
22
+ console.info(result)
23
+ while (n) {
24
+ result[n.x + size][n.y + size][n.z + size] = pad(counter)
25
+ counter = counter + 1
26
+ n = iter.next()
27
+ }
28
+ let str = 'Layer 0: ...\n'
29
+ for (let x = 0; x < size * 2; x++) {
30
+ let line = ''
31
+ for (let y = 0; y < size * 2; y++) {
32
+ for (let z = 0; z < size * 2; z++) {
33
+ line += '|' + pad(result[x][y][z])
34
+ }
35
+ line += ' '
36
+ }
37
+ str += line + '\n'
38
+ }
39
+ return str
40
+ }
41
+
42
+ function iterate2d (iter) {
43
+ let n = iter.next()
44
+ const result = []
45
+ const size = 5
46
+ let counter = 0
47
+ for (let x = 0; x < size * 2; x++) {
48
+ for (let z = 0; z < size * 2; z++) {
49
+ if (!result[x]) result[x] = []
50
+ result[x][z] = ' '
51
+ }
52
+ }
53
+ while (n) {
54
+ result[n.x + size][n.z + size] = pad(counter)
55
+ counter = counter + 1
56
+ n = iter.next()
57
+ }
58
+ let str = ''
59
+ for (let x = 0; x < size * 2; x++) {
60
+ for (let z = 0; z < size * 2; z++) {
61
+ str += '|' + result[x][z]
62
+ }
63
+ str += '|\n'
64
+ }
65
+ return str
66
+ }
67
+
68
+ function pad (num) {
69
+ return num.toString().padStart(3, ' ')
12
70
  }
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "prismarine-world",
3
- "version": "3.4.0",
3
+ "version": "3.6.1",
4
4
  "description": "The core implementation of the world for prismarine",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
7
  "pretest": "npm run lint",
8
8
  "lint": "standard",
9
9
  "fix": "standard --fix",
10
- "test": "jest --verbose"
10
+ "test": "mocha --reporter spec --exit"
11
11
  },
12
12
  "repository": {
13
13
  "type": "git",
@@ -21,7 +21,7 @@
21
21
  "game"
22
22
  ],
23
23
  "engines": {
24
- "nodejs": ">=8.0.0"
24
+ "node": ">=8.0.0"
25
25
  },
26
26
  "enginesStrict": true,
27
27
  "author": "Will Franzen <wtfranzen@gmail.com> (http://will.xyz/)",
@@ -33,19 +33,20 @@
33
33
  "devDependencies": {
34
34
  "buffer-equal": "^1.0.0",
35
35
  "flatmap": "0.0.3",
36
- "jest": "^26.0.1",
37
- "minecraft-data": "^2.47.0",
36
+ "minecraft-data": "^3.0.0",
38
37
  "mkdirp": "^0.5.1",
39
38
  "prismarine-chunk": "^1.14.0",
39
+ "prismarine-world": "file:.",
40
40
  "prismarine-provider-anvil": "^2.0.0",
41
41
  "prismarine-provider-raw": "^1.0.1",
42
+ "process": "^0.11.0",
42
43
  "range": "0.0.3",
43
44
  "rimraf": "^3.0.2",
44
45
  "standard": "^16.0.1",
45
- "process": "^0.11.0"
46
+ "expect": "^27.3.1",
47
+ "mocha": "^9.1.3"
46
48
  },
47
49
  "dependencies": {
48
- "event-promise": "0.0.1",
49
- "vec3": "~0.1.3"
50
+ "vec3": "^0.1.7"
50
51
  }
51
52
  }
package/src/iterators.js CHANGED
@@ -1,11 +1,21 @@
1
1
  const { Vec3 } = require('vec3')
2
2
 
3
+ const BlockFace = {
4
+ UNKNOWN: -999,
5
+ BOTTOM: 0,
6
+ TOP: 1,
7
+ NORTH: 2,
8
+ SOUTH: 3,
9
+ WEST: 4,
10
+ EAST: 5
11
+ }
12
+
3
13
  // 2D spiral iterator, useful to iterate on
4
14
  // columns that are centered on bot position
5
15
  // https://en.wikipedia.org/wiki/Taxicab_geometry
6
16
  class ManhattanIterator {
7
17
  constructor (x, y, maxDistance) {
8
- this.maxDistance = maxDistance
18
+ this.maxDistance = Math.floor(maxDistance)
9
19
  this.startx = x
10
20
  this.starty = y
11
21
  this.x = 2
@@ -90,16 +100,6 @@ class OctahedronIterator {
90
100
  }
91
101
  }
92
102
 
93
- const BlockFace = {
94
- UNKNOWN: -999,
95
- BOTTOM: 0,
96
- TOP: 1,
97
- NORTH: 2,
98
- SOUTH: 3,
99
- WEST: 4,
100
- EAST: 5
101
- }
102
-
103
103
  // This iterate along a ray starting at `pos` in `dir` direction
104
104
  // It steps exactly 1 block at a time, returning the block coordinates
105
105
  // and the face by which the ray entered the block.
@@ -204,10 +204,75 @@ class RaycastIterator {
204
204
  }
205
205
  }
206
206
 
207
+ class SpiralIterator2d {
208
+ /**
209
+ * Spiral outwards from a central position in growing squares.
210
+ * Every point has a constant distance to its previous and following position of 1. First point returned is the starting position.
211
+ * Generates positions like this:
212
+ * ```text
213
+ * 16 15 14 13 12
214
+ * 17 4 3 2 11
215
+ * 18 5 0 1 10
216
+ * 19 6 7 8 9
217
+ * 20 21 22 23 24
218
+ * (maxDistance = 2; points returned = 25)
219
+ * ```
220
+ * Copy and past warrior source: https://stackoverflow.com/questions/3706219/algorithm-for-iterating-over-an-outward-spiral-on-a-discrete-2d-grid-from-the-or
221
+ * @param {Vec3} pos Starting position
222
+ * @param {number} maxDistance Max distance from starting position
223
+ */
224
+ constructor (pos, maxDistance) {
225
+ this.start = pos
226
+ this.maxDistance = maxDistance
227
+
228
+ this.NUMBER_OF_POINTS = Math.floor(Math.pow((Math.floor(maxDistance) - 0.5) * 2, 2))
229
+
230
+ // (di, dj) is a vector - direction in which we move right now
231
+ this.di = 1
232
+ this.dj = 0
233
+ // length of current segment
234
+ this.segment_length = 1
235
+ // current position (i, j) and how much of current segment we passed
236
+ this.i = 0
237
+ this.j = 0
238
+ this.segment_passed = 0
239
+ // current iteration
240
+ this.k = 0
241
+ }
242
+
243
+ next () {
244
+ if (this.k >= this.NUMBER_OF_POINTS) return null
245
+ const output = this.start.offset(this.i, 0, this.j)
246
+
247
+ // make a step, add 'direction' vector (di, dj) to current position (i, j)
248
+ this.i += this.di
249
+ this.j += this.dj
250
+ this.segment_passed += 1
251
+
252
+ if (this.segment_passed === this.segment_length) {
253
+ // done with current segment
254
+ this.segment_passed = 0
255
+
256
+ // 'rotate' directions
257
+ const buffer = this.di
258
+ this.di = -this.dj
259
+ this.dj = buffer
260
+
261
+ // increase segment length if necessary
262
+ if (this.dj === 0) {
263
+ this.segment_length += 1
264
+ }
265
+ }
266
+ this.k += 1
267
+ return output
268
+ }
269
+ }
270
+
207
271
  module.exports = {
208
272
  ManhattanIterator,
209
273
  ManathanIterator: ManhattanIterator, // backward compatibility
210
274
  OctahedronIterator,
211
275
  RaycastIterator,
276
+ SpiralIterator2d,
212
277
  BlockFace
213
278
  }
package/src/world.js CHANGED
@@ -2,7 +2,7 @@ const { Vec3 } = require('vec3')
2
2
  const { EventEmitter } = require('events')
3
3
  const { RaycastIterator } = require('./iterators')
4
4
  const WorldSync = require('./worldsync')
5
- const once = require('event-promise')
5
+ const { once } = require('events')
6
6
 
7
7
  function columnKeyXZ (chunkX, chunkZ) {
8
8
  return chunkX + ',' + chunkZ
@@ -64,7 +64,6 @@ class World extends EventEmitter {
64
64
  if (block && (!matcher || matcher(block))) {
65
65
  const intersect = iter.intersect(block.shapes, position)
66
66
  if (intersect) {
67
- block.position = position
68
67
  block.face = intersect.face
69
68
  block.intersect = intersect.pos
70
69
  return block
@@ -101,6 +100,8 @@ class World extends EventEmitter {
101
100
  }
102
101
 
103
102
  _emitBlockUpdate (oldBlock, newBlock, position) {
103
+ oldBlock.position = position.floored()
104
+ newBlock.position = oldBlock.position
104
105
  this.emit('blockUpdate', oldBlock, newBlock)
105
106
  this.emit(`blockUpdate:${position}`, oldBlock, newBlock)
106
107
  }
@@ -202,7 +203,9 @@ class World extends EventEmitter {
202
203
  }
203
204
 
204
205
  async getBlock (pos) {
205
- return (await this.getColumnAt(pos)).getBlock(posInChunk(pos))
206
+ const block = (await this.getColumnAt(pos)).getBlock(posInChunk(pos))
207
+ block.position = pos.floored()
208
+ return block
206
209
  }
207
210
 
208
211
  async getBlockStateId (pos) {
package/src/worldsync.js CHANGED
@@ -43,13 +43,18 @@ class WorldSync extends EventEmitter {
43
43
  while (pos) {
44
44
  const position = new Vec3(pos.x, pos.y, pos.z)
45
45
  const block = this.getBlock(position)
46
- if (block && (!matcher || matcher(block))) {
47
- const intersect = iter.intersect(block.shapes, position)
48
- if (intersect) {
49
- block.position = position
50
- block.face = intersect.face
51
- block.intersect = intersect.pos
52
- return block
46
+ if (block) {
47
+ if (matcher) {
48
+ if (matcher(block, iter)) {
49
+ return block
50
+ }
51
+ } else {
52
+ const intersect = iter.intersect(block.shapes, position)
53
+ if (intersect) {
54
+ block.face = intersect.face
55
+ block.intersect = intersect.pos
56
+ return block
57
+ }
53
58
  }
54
59
  }
55
60
  pos = iter.next()
@@ -58,8 +63,10 @@ class WorldSync extends EventEmitter {
58
63
  }
59
64
 
60
65
  _emitBlockUpdate (oldBlock, newBlock, position) {
66
+ oldBlock.position = position.floored()
67
+ newBlock.position = oldBlock.position
61
68
  this.emit('blockUpdate', oldBlock, newBlock)
62
- if (position) this.emit(`blockUpdate:${position}`, oldBlock, newBlock)
69
+ this.emit(`blockUpdate:${position}`, oldBlock, newBlock)
63
70
  }
64
71
 
65
72
  unloadColumn (chunkX, chunkZ) {
@@ -91,7 +98,9 @@ class WorldSync extends EventEmitter {
91
98
  getBlock (pos) {
92
99
  const chunk = this.getColumnAt(pos)
93
100
  if (!chunk) return null
94
- return chunk.getBlock(posInChunk(pos))
101
+ const block = chunk.getBlock(posInChunk(pos))
102
+ block.position = pos.floored()
103
+ return block
95
104
  }
96
105
 
97
106
  getBlockStateId (pos) {
@@ -137,7 +146,7 @@ class WorldSync extends EventEmitter {
137
146
  const oldBlock = chunk.getBlock(pInChunk)
138
147
  chunk.setBlock(pInChunk, block)
139
148
  this.async.saveAt(pos)
140
- this._emitBlockUpdate(oldBlock, block)
149
+ this._emitBlockUpdate(oldBlock, block, pos)
141
150
  }
142
151
 
143
152
  setBlockStateId (pos, stateId) {
@@ -0,0 +1,17 @@
1
+ /* eslint-env mocha */
2
+
3
+ const { SpiralIterator2d } = require('../src/iterators')
4
+ const { Vec3 } = require('vec3')
5
+ const expect = require('expect')
6
+
7
+ describe('Spiral iterator', () => {
8
+ it('simple function test', async () => {
9
+ const startPos = new Vec3(0, 0, 0)
10
+ const iter = new SpiralIterator2d(startPos, 2)
11
+ const first = iter.next()
12
+ const second = iter.next()
13
+
14
+ expect(first.x === startPos.x && first.y === startPos.y && first.z === startPos.z).toBeTruthy()
15
+ expect(second.x === startPos.x && second.y === startPos.y && second.z === startPos.z).toBeFalsy()
16
+ })
17
+ })
@@ -1,4 +1,4 @@
1
- /* eslint-env jest */
1
+ /* eslint-env mocha */
2
2
 
3
3
  const World = require('prismarine-world')('1.16.4')
4
4
  const Chunk = require('prismarine-chunk')('1.16.4')
package/test/test.js CHANGED
@@ -1,4 +1,4 @@
1
- /* eslint-env jest */
1
+ /* eslint-env mocha */
2
2
 
3
3
  const flatMap = require('flatmap')
4
4
  const range = require('range').range
@@ -28,11 +28,11 @@ describe('saving and loading works', function () {
28
28
  }
29
29
 
30
30
  const regionPath = 'world/testRegion'
31
- beforeAll((cb) => {
31
+ before((cb) => {
32
32
  mkdirp(regionPath, cb)
33
33
  })
34
34
 
35
- afterAll(cb => {
35
+ after(cb => {
36
36
  rimraf(regionPath, cb)
37
37
  })
38
38
 
@@ -87,11 +87,11 @@ describe('Synchronous saving and loading works', function () {
87
87
  }
88
88
 
89
89
  const regionPath = 'world/testRegionSync'
90
- beforeAll((cb) => {
90
+ before((cb) => {
91
91
  mkdirp(regionPath, cb)
92
92
  })
93
93
 
94
- afterAll(cb => {
94
+ after(cb => {
95
95
  rimraf(regionPath, cb)
96
96
  })
97
97