@starktma/minecraft-utils 1.3.111 → 1.5.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/README.md +56 -0
- package/dist/constants.d.ts +26 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +34 -0
- package/dist/constants.js.map +1 -0
- package/dist/database/database.d.ts +8 -5
- package/dist/database/database.d.ts.map +1 -1
- package/dist/database/database.js +40 -38
- package/dist/database/database.js.map +1 -1
- package/dist/database/index.d.ts +1 -3
- package/dist/database/index.d.ts.map +1 -1
- package/dist/database/index.js +1 -2
- package/dist/database/index.js.map +1 -1
- package/dist/game-state-machine/branch.js +2 -2
- package/dist/game-state-machine/branch.js.map +1 -1
- package/dist/game-state-machine/database.d.ts +10 -3
- package/dist/game-state-machine/database.d.ts.map +1 -1
- package/dist/game-state-machine/database.js +20 -2
- package/dist/game-state-machine/database.js.map +1 -1
- package/dist/game-state-machine/index.d.ts +1 -2
- package/dist/game-state-machine/index.d.ts.map +1 -1
- package/dist/game-state-machine/index.js +1 -2
- package/dist/game-state-machine/index.js.map +1 -1
- package/dist/game-state-machine/stateMachine.d.ts +6 -9
- package/dist/game-state-machine/stateMachine.d.ts.map +1 -1
- package/dist/game-state-machine/stateMachine.js +72 -86
- package/dist/game-state-machine/stateMachine.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/math/BFSScanner.d.ts +117 -0
- package/dist/math/BFSScanner.d.ts.map +1 -0
- package/dist/math/BFSScanner.js +388 -0
- package/dist/math/BFSScanner.js.map +1 -0
- package/dist/math/Perlin2D.d.ts +12 -0
- package/dist/math/Perlin2D.d.ts.map +1 -0
- package/dist/math/Perlin2D.js +115 -0
- package/dist/math/Perlin2D.js.map +1 -0
- package/dist/math/index.d.ts +63 -59
- package/dist/math/index.d.ts.map +1 -1
- package/dist/math/index.js +150 -76
- package/dist/math/index.js.map +1 -1
- package/dist/minecraft/effectsAPI.d.ts +69 -0
- package/dist/minecraft/effectsAPI.d.ts.map +1 -0
- package/dist/minecraft/effectsAPI.js +441 -0
- package/dist/minecraft/effectsAPI.js.map +1 -0
- package/dist/minecraft/index.d.ts +7 -3
- package/dist/minecraft/index.d.ts.map +1 -1
- package/dist/minecraft/index.js +53 -29
- package/dist/minecraft/index.js.map +1 -1
- package/dist/minecraft/projectileAPI.d.ts +23 -0
- package/dist/minecraft/projectileAPI.d.ts.map +1 -0
- package/dist/minecraft/projectileAPI.js +148 -0
- package/dist/minecraft/projectileAPI.js.map +1 -0
- package/dist/minecraft/structuresAPI.d.ts +11 -0
- package/dist/minecraft/structuresAPI.d.ts.map +1 -0
- package/dist/minecraft/structuresAPI.js +66 -0
- package/dist/minecraft/structuresAPI.js.map +1 -0
- package/package.json +7 -3
- package/dist/database/constants.d.ts +0 -2
- package/dist/database/constants.d.ts.map +0 -1
- package/dist/database/constants.js +0 -2
- package/dist/database/constants.js.map +0 -1
- package/dist/game-state-machine/constants.d.ts +0 -2
- package/dist/game-state-machine/constants.d.ts.map +0 -1
- package/dist/game-state-machine/constants.js +0 -2
- package/dist/game-state-machine/constants.js.map +0 -1
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents the result of a scan, stored as an optimized chunked heightmap.
|
|
3
|
+
* Allows for infinite expansion without reallocation.
|
|
4
|
+
*/
|
|
5
|
+
export class ScanResult {
|
|
6
|
+
// Chunk size (16x16 cells)
|
|
7
|
+
static CHUNK_SIZE = 16;
|
|
8
|
+
static CHUNK_MASK = 0xf;
|
|
9
|
+
static CHUNK_SHIFT = 4;
|
|
10
|
+
static SENTINEL = -2147483648;
|
|
11
|
+
// Cell size (8x8 blocks)
|
|
12
|
+
static CELL_SIZE = 8;
|
|
13
|
+
static CELL_SHIFT = 3; // 2^3 = 8
|
|
14
|
+
// Map of chunk key "chunkX,chunkZ" -> Int32Array(256)
|
|
15
|
+
chunks = new Map();
|
|
16
|
+
constructor() { }
|
|
17
|
+
/**
|
|
18
|
+
* Updates the height at the given coordinates if the new Y is higher.
|
|
19
|
+
* @param x Absolute X coordinate
|
|
20
|
+
* @param z Absolute Z coordinate
|
|
21
|
+
* @param y Absolute Y coordinate
|
|
22
|
+
*/
|
|
23
|
+
updateHeight(x, z, y) {
|
|
24
|
+
// Convert world coords to cell coords
|
|
25
|
+
const cellX = x >> ScanResult.CELL_SHIFT;
|
|
26
|
+
const cellZ = z >> ScanResult.CELL_SHIFT;
|
|
27
|
+
const chunkX = cellX >> ScanResult.CHUNK_SHIFT;
|
|
28
|
+
const chunkZ = cellZ >> ScanResult.CHUNK_SHIFT;
|
|
29
|
+
const key = `${chunkX},${chunkZ}`;
|
|
30
|
+
let chunk = this.chunks.get(key);
|
|
31
|
+
if (!chunk) {
|
|
32
|
+
chunk = new Int32Array(ScanResult.CHUNK_SIZE * ScanResult.CHUNK_SIZE).fill(ScanResult.SENTINEL);
|
|
33
|
+
this.chunks.set(key, chunk);
|
|
34
|
+
}
|
|
35
|
+
const localX = cellX & ScanResult.CHUNK_MASK;
|
|
36
|
+
const localZ = cellZ & ScanResult.CHUNK_MASK;
|
|
37
|
+
const index = (localZ << ScanResult.CHUNK_SHIFT) | localX;
|
|
38
|
+
if (y > chunk[index]) {
|
|
39
|
+
chunk[index] = y;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Retrieves the highest Y coordinate found at the given X, Z.
|
|
44
|
+
* @param x Absolute X coordinate
|
|
45
|
+
* @param z Absolute Z coordinate
|
|
46
|
+
* @returns The Y coordinate, or undefined if no block was scanned at this location.
|
|
47
|
+
*/
|
|
48
|
+
getHeight(x, z) {
|
|
49
|
+
const cellX = x >> ScanResult.CELL_SHIFT;
|
|
50
|
+
const cellZ = z >> ScanResult.CELL_SHIFT;
|
|
51
|
+
const chunkX = cellX >> ScanResult.CHUNK_SHIFT;
|
|
52
|
+
const chunkZ = cellZ >> ScanResult.CHUNK_SHIFT;
|
|
53
|
+
const key = `${chunkX},${chunkZ}`;
|
|
54
|
+
const chunk = this.chunks.get(key);
|
|
55
|
+
if (!chunk)
|
|
56
|
+
return undefined;
|
|
57
|
+
const localX = cellX & ScanResult.CHUNK_MASK;
|
|
58
|
+
const localZ = cellZ & ScanResult.CHUNK_MASK;
|
|
59
|
+
const index = (localZ << ScanResult.CHUNK_SHIFT) | localX;
|
|
60
|
+
const val = chunk[index];
|
|
61
|
+
return val === ScanResult.SENTINEL ? undefined : val;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Checks if a location has a valid height recorded.
|
|
65
|
+
*/
|
|
66
|
+
hasHeight(x, z) {
|
|
67
|
+
return this.getHeight(x, z) !== undefined;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Clears all scan data.
|
|
71
|
+
*/
|
|
72
|
+
clear() {
|
|
73
|
+
this.chunks.clear();
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Returns a random valid position from the scanned area.
|
|
77
|
+
* @param center Optional center position to constrain the random pick.
|
|
78
|
+
* @param minRadius Optional minimum radius from center.
|
|
79
|
+
* @param maxRadius Optional maximum radius from center.
|
|
80
|
+
* @param filter Optional filter function to validate the position.
|
|
81
|
+
* @returns A Vector3 with the position, or undefined if no data exists.
|
|
82
|
+
*/
|
|
83
|
+
getRandomPosition(center, minRadius, maxRadius, filter) {
|
|
84
|
+
if (this.chunks.size === 0)
|
|
85
|
+
return undefined;
|
|
86
|
+
let keys = Array.from(this.chunks.keys());
|
|
87
|
+
// Optimization: Filter chunks if center/maxRadius provided
|
|
88
|
+
if (center && maxRadius) {
|
|
89
|
+
// Convert center/radius to chunk coords
|
|
90
|
+
// Radius in blocks -> Radius in chunks?
|
|
91
|
+
// Max radius in blocks.
|
|
92
|
+
// Chunk size in blocks = 16 * 8 = 128.
|
|
93
|
+
const chunkSizeInBlocks = ScanResult.CHUNK_SIZE * ScanResult.CELL_SIZE;
|
|
94
|
+
const minChunkX = (center.x - maxRadius) >> (ScanResult.CHUNK_SHIFT + ScanResult.CELL_SHIFT);
|
|
95
|
+
const maxChunkX = (center.x + maxRadius) >> (ScanResult.CHUNK_SHIFT + ScanResult.CELL_SHIFT);
|
|
96
|
+
const minChunkZ = (center.z - maxRadius) >> (ScanResult.CHUNK_SHIFT + ScanResult.CELL_SHIFT);
|
|
97
|
+
const maxChunkZ = (center.z + maxRadius) >> (ScanResult.CHUNK_SHIFT + ScanResult.CELL_SHIFT);
|
|
98
|
+
keys = keys.filter((key) => {
|
|
99
|
+
const [cxStr, czStr] = key.split(",");
|
|
100
|
+
const cx = parseInt(cxStr);
|
|
101
|
+
const cz = parseInt(czStr);
|
|
102
|
+
return cx >= minChunkX && cx <= maxChunkX && cz >= minChunkZ && cz <= maxChunkZ;
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
if (keys.length === 0)
|
|
106
|
+
return undefined;
|
|
107
|
+
const tryFind = (enforceMin) => {
|
|
108
|
+
for (let attempt = 0; attempt < 20; attempt++) {
|
|
109
|
+
const randomKey = keys[Math.floor(Math.random() * keys.length)];
|
|
110
|
+
const chunk = this.chunks.get(randomKey);
|
|
111
|
+
const [chunkXStr, chunkZStr] = randomKey.split(",");
|
|
112
|
+
const chunkX = parseInt(chunkXStr);
|
|
113
|
+
const chunkZ = parseInt(chunkZStr);
|
|
114
|
+
for (let i = 0; i < 5; i++) {
|
|
115
|
+
const localX = Math.floor(Math.random() * ScanResult.CHUNK_SIZE);
|
|
116
|
+
const localZ = Math.floor(Math.random() * ScanResult.CHUNK_SIZE);
|
|
117
|
+
const index = (localZ << ScanResult.CHUNK_SHIFT) | localX;
|
|
118
|
+
const y = chunk[index];
|
|
119
|
+
if (y !== ScanResult.SENTINEL) {
|
|
120
|
+
// Convert back to world coordinates (first coordinate of the cell)
|
|
121
|
+
const cellX = (chunkX << ScanResult.CHUNK_SHIFT) + localX;
|
|
122
|
+
const cellZ = (chunkZ << ScanResult.CHUNK_SHIFT) + localZ;
|
|
123
|
+
const x = cellX << ScanResult.CELL_SHIFT;
|
|
124
|
+
const z = cellZ << ScanResult.CELL_SHIFT;
|
|
125
|
+
const pos = { x, y, z };
|
|
126
|
+
if (center && maxRadius) {
|
|
127
|
+
const dx = x - center.x;
|
|
128
|
+
const dz = z - center.z;
|
|
129
|
+
const distSq = dx * dx + dz * dz;
|
|
130
|
+
if (distSq > maxRadius * maxRadius)
|
|
131
|
+
continue;
|
|
132
|
+
if (enforceMin && minRadius && distSq < minRadius * minRadius)
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
if (filter && !filter(pos))
|
|
136
|
+
continue;
|
|
137
|
+
return pos;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return undefined;
|
|
142
|
+
};
|
|
143
|
+
// First attempt: Respect minRadius
|
|
144
|
+
let pos = tryFind(true);
|
|
145
|
+
// Second attempt: If failed and minRadius was requested, find the farthest available position
|
|
146
|
+
if (!pos && minRadius && center) {
|
|
147
|
+
// Sort keys by distance from center (descending)
|
|
148
|
+
keys.sort((a, b) => {
|
|
149
|
+
const [axStr, azStr] = a.split(",");
|
|
150
|
+
const [bxStr, bzStr] = b.split(",");
|
|
151
|
+
const ax = parseInt(axStr);
|
|
152
|
+
const az = parseInt(azStr);
|
|
153
|
+
const bx = parseInt(bxStr);
|
|
154
|
+
const bz = parseInt(bzStr);
|
|
155
|
+
.0; // Approximate distance using chunk coordinates
|
|
156
|
+
const cx = center.x >> (ScanResult.CHUNK_SHIFT + ScanResult.CELL_SHIFT);
|
|
157
|
+
const cz = center.z >> (ScanResult.CHUNK_SHIFT + ScanResult.CELL_SHIFT);
|
|
158
|
+
const distA = (ax - cx) ** 2 + (az - cz) ** 2;
|
|
159
|
+
const distB = (bx - cx) ** 2 + (bz - cz) ** 2;
|
|
160
|
+
return distB - distA;
|
|
161
|
+
});
|
|
162
|
+
for (const key of keys) {
|
|
163
|
+
const chunk = this.chunks.get(key);
|
|
164
|
+
const [chunkXStr, chunkZStr] = key.split(",");
|
|
165
|
+
const chunkX = parseInt(chunkXStr);
|
|
166
|
+
const chunkZ = parseInt(chunkZStr);
|
|
167
|
+
let maxDistSq = -1;
|
|
168
|
+
let bestPos;
|
|
169
|
+
for (let i = 0; i < chunk.length; i++) {
|
|
170
|
+
const y = chunk[i];
|
|
171
|
+
if (y !== ScanResult.SENTINEL) {
|
|
172
|
+
const localX = i & ScanResult.CHUNK_MASK;
|
|
173
|
+
const localZ = i >> ScanResult.CHUNK_SHIFT;
|
|
174
|
+
const cellX = (chunkX << ScanResult.CHUNK_SHIFT) + localX;
|
|
175
|
+
const cellZ = (chunkZ << ScanResult.CHUNK_SHIFT) + localZ;
|
|
176
|
+
const x = cellX << ScanResult.CELL_SHIFT;
|
|
177
|
+
const z = cellZ << ScanResult.CELL_SHIFT;
|
|
178
|
+
const pos = { x, y, z };
|
|
179
|
+
if (filter && !filter(pos))
|
|
180
|
+
continue;
|
|
181
|
+
const dx = x - center.x;
|
|
182
|
+
const dz = z - center.z;
|
|
183
|
+
const distSq = dx * dx + dz * dz;
|
|
184
|
+
if (distSq > maxDistSq) {
|
|
185
|
+
maxDistSq = distSq;
|
|
186
|
+
bestPos = pos;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (bestPos) {
|
|
191
|
+
pos = bestPos;
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return pos;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* A highly optimized BFS Scanner using the Singleton pattern.
|
|
201
|
+
*/
|
|
202
|
+
export class BFSScanner {
|
|
203
|
+
static instance;
|
|
204
|
+
// Reusable vector to avoid allocation during getBlock
|
|
205
|
+
tempPos = { x: 0, y: 0, z: 0 };
|
|
206
|
+
// Directions: North, South, East, West (Scaled by CELL_SIZE)
|
|
207
|
+
directions = [
|
|
208
|
+
{ x: ScanResult.CELL_SIZE, y: 0, z: 0 },
|
|
209
|
+
{ x: -ScanResult.CELL_SIZE, y: 0, z: 0 },
|
|
210
|
+
{ x: 0, y: 0, z: ScanResult.CELL_SIZE },
|
|
211
|
+
{ x: 0, y: 0, z: -ScanResult.CELL_SIZE },
|
|
212
|
+
];
|
|
213
|
+
// Global storage for scan results per dimension
|
|
214
|
+
globalScanResults = new Map();
|
|
215
|
+
constructor() { }
|
|
216
|
+
/**
|
|
217
|
+
* Gets the singleton instance of the BFSScanner.
|
|
218
|
+
*/
|
|
219
|
+
static getInstance() {
|
|
220
|
+
if (!BFSScanner.instance) {
|
|
221
|
+
BFSScanner.instance = new BFSScanner();
|
|
222
|
+
}
|
|
223
|
+
return BFSScanner.instance;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Retrieves the global scan result for a specific dimension.
|
|
227
|
+
* @param dimensionId The identifier of the dimension (e.g., "minecraft:overworld").
|
|
228
|
+
*/
|
|
229
|
+
getScanResult(dimensionId) {
|
|
230
|
+
if (!this.globalScanResults.has(dimensionId)) {
|
|
231
|
+
this.globalScanResults.set(dimensionId, new ScanResult());
|
|
232
|
+
}
|
|
233
|
+
return this.globalScanResults.get(dimensionId);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Performs the BFS scan asynchronously.
|
|
237
|
+
* @param dimension The dimension to scan in.
|
|
238
|
+
* @param config The scan configuration.
|
|
239
|
+
* @param existingResult Optional existing ScanResult to update/continue from.
|
|
240
|
+
* @returns A Generator resolving to the updated ScanResult.
|
|
241
|
+
*/
|
|
242
|
+
*scan(dimension, config, existingResult) {
|
|
243
|
+
const { center, shape, geometryDimensions, blockFilter, maxIterations = 10000, forceRescan = false, yieldInterval = 100, } = config;
|
|
244
|
+
const result = existingResult || new ScanResult();
|
|
245
|
+
// Optimization: Use Int32Array for queue to save memory compared to standard Array
|
|
246
|
+
// Initial size 1000 * 3 coordinates. Will grow if needed.
|
|
247
|
+
let queueCapacity = 3000;
|
|
248
|
+
let queue = new Int32Array(queueCapacity);
|
|
249
|
+
let qHead = 0;
|
|
250
|
+
let qTail = 0;
|
|
251
|
+
const pushToQueue = (x, y, z) => {
|
|
252
|
+
if (qTail + 3 >= queueCapacity) {
|
|
253
|
+
// Grow queue
|
|
254
|
+
const newCapacity = queueCapacity * 2;
|
|
255
|
+
const newQueue = new Int32Array(newCapacity);
|
|
256
|
+
newQueue.set(queue);
|
|
257
|
+
queue = newQueue;
|
|
258
|
+
queueCapacity = newCapacity;
|
|
259
|
+
}
|
|
260
|
+
queue[qTail++] = x;
|
|
261
|
+
queue[qTail++] = y;
|
|
262
|
+
queue[qTail++] = z;
|
|
263
|
+
};
|
|
264
|
+
// Start at center, aligned to cell grid
|
|
265
|
+
const startX = Math.floor(center.x / ScanResult.CELL_SIZE) * ScanResult.CELL_SIZE;
|
|
266
|
+
const startY = Math.floor(center.y);
|
|
267
|
+
const startZ = Math.floor(center.z / ScanResult.CELL_SIZE) * ScanResult.CELL_SIZE;
|
|
268
|
+
pushToQueue(startX, startY, startZ);
|
|
269
|
+
// Optimization: Use a Map<number, Set<number>> for visited coordinates
|
|
270
|
+
// Key: (cellX & 0xffff) | ((cellZ & 0xffff) << 16), Value: Set of y coordinates
|
|
271
|
+
const visitedXZ = new Map();
|
|
272
|
+
const markVisited = (x, y, z) => {
|
|
273
|
+
const cellX = x >> 3; // Divide by 8
|
|
274
|
+
const cellZ = z >> 3;
|
|
275
|
+
const key = (cellX & 0xffff) | ((cellZ & 0xffff) << 16);
|
|
276
|
+
let ySet = visitedXZ.get(key);
|
|
277
|
+
if (!ySet) {
|
|
278
|
+
ySet = new Set();
|
|
279
|
+
visitedXZ.set(key, ySet);
|
|
280
|
+
}
|
|
281
|
+
ySet.add(y);
|
|
282
|
+
};
|
|
283
|
+
const isVisited = (x, y, z) => {
|
|
284
|
+
const cellX = x >> 3;
|
|
285
|
+
const cellZ = z >> 3;
|
|
286
|
+
const key = (cellX & 0xffff) | ((cellZ & 0xffff) << 16);
|
|
287
|
+
const ySet = visitedXZ.get(key);
|
|
288
|
+
return ySet ? ySet.has(y) : false;
|
|
289
|
+
};
|
|
290
|
+
markVisited(startX, startY, startZ);
|
|
291
|
+
// Pre-calculate squared radius for distance checks
|
|
292
|
+
const rSq = geometryDimensions.x * geometryDimensions.x;
|
|
293
|
+
let iterations = 0;
|
|
294
|
+
let processedSinceYield = 0;
|
|
295
|
+
while (qHead < qTail) {
|
|
296
|
+
if (iterations++ > maxIterations)
|
|
297
|
+
break;
|
|
298
|
+
// Yield to event loop periodically
|
|
299
|
+
if (processedSinceYield++ >= yieldInterval) {
|
|
300
|
+
processedSinceYield = 0;
|
|
301
|
+
yield;
|
|
302
|
+
}
|
|
303
|
+
const cx = queue[qHead++];
|
|
304
|
+
const cy = queue[qHead++];
|
|
305
|
+
const cz = queue[qHead++];
|
|
306
|
+
// Check if already scanned
|
|
307
|
+
const alreadyScanned = result.hasHeight(cx, cz);
|
|
308
|
+
let shouldProcessNeighbors = false;
|
|
309
|
+
if (alreadyScanned && !forceRescan) {
|
|
310
|
+
// Optimization: Skip expensive block checks.
|
|
311
|
+
// We assume if it's in the result, it was valid.
|
|
312
|
+
// We MUST process neighbors to reach the edge of the known area.
|
|
313
|
+
shouldProcessNeighbors = true;
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
// Not scanned or forced rescan: Do the expensive check
|
|
317
|
+
this.tempPos.x = cx;
|
|
318
|
+
this.tempPos.y = cy;
|
|
319
|
+
this.tempPos.z = cz;
|
|
320
|
+
// Geometry Check (Fastest)
|
|
321
|
+
if (!this.isWithinShape(cx, cy, cz, center, shape, geometryDimensions, rSq)) {
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
let isValid = true;
|
|
325
|
+
// Check 8x8 volume
|
|
326
|
+
try {
|
|
327
|
+
for (let dx = 0; dx < ScanResult.CELL_SIZE; dx++) {
|
|
328
|
+
for (let dz = 0; dz < ScanResult.CELL_SIZE; dz++) {
|
|
329
|
+
this.tempPos.x = cx + dx;
|
|
330
|
+
this.tempPos.z = cz + dz;
|
|
331
|
+
const block = dimension.getBlock(this.tempPos);
|
|
332
|
+
if (!block || !blockFilter(block)) {
|
|
333
|
+
isValid = false;
|
|
334
|
+
break;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
if (!isValid)
|
|
338
|
+
break;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
catch (e) {
|
|
342
|
+
isValid = false;
|
|
343
|
+
}
|
|
344
|
+
if (isValid) {
|
|
345
|
+
result.updateHeight(cx, cz, cy);
|
|
346
|
+
shouldProcessNeighbors = true;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
if (shouldProcessNeighbors) {
|
|
350
|
+
for (const dir of this.directions) {
|
|
351
|
+
const nx = cx + dir.x;
|
|
352
|
+
const ny = cy + dir.y;
|
|
353
|
+
const nz = cz + dir.z;
|
|
354
|
+
// Check geometry for neighbors before adding to queue to save iterations
|
|
355
|
+
if (!this.isWithinShape(nx, ny, nz, center, shape, geometryDimensions, rSq)) {
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
358
|
+
if (isVisited(nx, ny, nz))
|
|
359
|
+
continue;
|
|
360
|
+
markVisited(nx, ny, nz);
|
|
361
|
+
pushToQueue(nx, ny, nz);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
// console.warn(`Scan finished. Iterations: ${iterations}, Queue: ${qTail/3}, Result Chunks: ${result['chunks'].size}`);
|
|
366
|
+
return result;
|
|
367
|
+
}
|
|
368
|
+
getCoordKey(x, y, z) {
|
|
369
|
+
return `${x},${y},${z}`;
|
|
370
|
+
}
|
|
371
|
+
isWithinShape(x, y, z, center, shape, dims, rSq) {
|
|
372
|
+
const dx = x - center.x;
|
|
373
|
+
const dy = y - center.y;
|
|
374
|
+
const dz = z - center.z;
|
|
375
|
+
switch (shape) {
|
|
376
|
+
case "cube":
|
|
377
|
+
return Math.abs(dx) <= dims.x && Math.abs(dy) <= dims.y && Math.abs(dz) <= dims.z;
|
|
378
|
+
case "sphere":
|
|
379
|
+
return dx * dx + dy * dy + dz * dz <= rSq;
|
|
380
|
+
case "cylinder":
|
|
381
|
+
// Cylinder assumed vertical (Y-axis)
|
|
382
|
+
return dx * dx + dz * dz <= rSq && Math.abs(dy) <= dims.y;
|
|
383
|
+
default:
|
|
384
|
+
return false;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
//# sourceMappingURL=BFSScanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BFSScanner.js","sourceRoot":"","sources":["../../src/math/BFSScanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare class Perlin2D {
|
|
2
|
+
private static _instances;
|
|
3
|
+
private perm;
|
|
4
|
+
static getInstance(seed?: number): Perlin2D;
|
|
5
|
+
constructor(seed?: number);
|
|
6
|
+
private fade;
|
|
7
|
+
private grad;
|
|
8
|
+
private lerp;
|
|
9
|
+
noise(x: number, y: number): number;
|
|
10
|
+
fbm(x: number, y: number, octaves: number, persistence: number): number;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=Perlin2D.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Perlin2D.d.ts","sourceRoot":"","sources":["../../src/math/Perlin2D.ts"],"names":[],"mappings":"AAaA,qBAAa,QAAQ;IACpB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAgC;IACzD,OAAO,CAAC,IAAI,CAAW;WAET,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ;gBAOtC,IAAI,SAAO;IAgCvB,OAAO,CAAC,IAAI;IAQZ,OAAO,CAAC,IAAI;IAaZ,OAAO,CAAC,IAAI;IAKZ,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM;IAiCnC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM;CAcvE"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// =================================================================================
|
|
2
|
+
// PERLIN NOISE (2D)
|
|
3
|
+
// =================================================================================
|
|
4
|
+
// We implement a compact, deterministic 2D Perlin:
|
|
5
|
+
// - A seedable xorshift32 RNG shuffles a 0..255 array into a permutation table.
|
|
6
|
+
// Why xorshift? Tiny, fast, deterministic — perfect for shuffling; cryptographic
|
|
7
|
+
// quality is unnecessary here.
|
|
8
|
+
// - Quintic fade (6t^5-15t^4+10t^3) ensures C2 continuity at lattice boundaries,
|
|
9
|
+
// preventing creases where cells meet.
|
|
10
|
+
// - Hash-derived gradient directions avoid storing a gradient table yet keep uniform
|
|
11
|
+
// angular spread (8 directions).
|
|
12
|
+
// - Standard bilinear interpolation with faded weights blends the 4 corner grads.
|
|
13
|
+
export class Perlin2D {
|
|
14
|
+
static _instances = {};
|
|
15
|
+
perm; // 512-length perm table (0..255 duplicated) for fast, wraparound indexing
|
|
16
|
+
static getInstance(seed) {
|
|
17
|
+
if (!this._instances[seed ?? 1337]) {
|
|
18
|
+
this._instances[seed ?? 1337] = new Perlin2D(seed);
|
|
19
|
+
}
|
|
20
|
+
return this._instances[seed ?? 1337];
|
|
21
|
+
}
|
|
22
|
+
constructor(seed = 1337) {
|
|
23
|
+
// --- Seeded RNG (xorshift32) — tiny & fast, good enough for permutation shuffle ---
|
|
24
|
+
// In other words, a fancy way to make a "pseudorandom number generator"
|
|
25
|
+
let state = seed | 0 || 1; // force 32-bit int; avoid 0 state by falling back to 1
|
|
26
|
+
const random = () => {
|
|
27
|
+
// Advance the state using xorshift recipe (Marsaglia):
|
|
28
|
+
state ^= state << 13; // mix high bits into low by left shift and XOR
|
|
29
|
+
state ^= state >>> 17; // spread entropy across the word with right shift XOR
|
|
30
|
+
state ^= state << 5; // another left shift XOR to finish the cycle
|
|
31
|
+
// // Convert unsigned 32-bit int to [0,1) float
|
|
32
|
+
return (state >>> 0) / 0xffffffff;
|
|
33
|
+
};
|
|
34
|
+
// Build base array [0..255]
|
|
35
|
+
const permutation = Array.from({ length: 256 }, (_, i) => i);
|
|
36
|
+
// Fisher-Yates shuffle using our seeded RNG for reproducibility
|
|
37
|
+
// In other words, a fancy way to "randomize" the array
|
|
38
|
+
// Pseudo-random, but deterministic given the same seed
|
|
39
|
+
for (let currentIndex = 255; currentIndex > 0; currentIndex--) {
|
|
40
|
+
const randomIndex = Math.floor(random() * (currentIndex + 1));
|
|
41
|
+
[permutation[currentIndex], permutation[randomIndex]] = [permutation[randomIndex], permutation[currentIndex]]; // swap
|
|
42
|
+
}
|
|
43
|
+
// Duplicate to 512 to allow cheap indexing with i & 255 and i+1 without bounds checks
|
|
44
|
+
this.perm = new Array(512);
|
|
45
|
+
for (let i = 0; i < 512; i++)
|
|
46
|
+
this.perm[i] = permutation[i & 255]; // i & 255 == i % 256
|
|
47
|
+
}
|
|
48
|
+
// Quintic fade: smoothstep with zero first/second derivatives at t=0 and t=1.
|
|
49
|
+
// Prevents visible grid seams when interpolating across cells.
|
|
50
|
+
// (6t^5-15t^4+10t^3) https://www.desmos.com/calculator/ykrjhcst6v
|
|
51
|
+
fade(weight) {
|
|
52
|
+
return weight * weight * weight * (weight * (6 * weight - 15) + 10);
|
|
53
|
+
}
|
|
54
|
+
// Derive a small set of 2D gradient directions from the hashed corner index.
|
|
55
|
+
// A dot product of the gradient and the (x,y) offset from the corner gives
|
|
56
|
+
// This calculates the alignment of our pseudorandom gradient value with XY
|
|
57
|
+
// and is used to determine the behaviour of the slope between the points.
|
|
58
|
+
grad(cornerHash, x, y) {
|
|
59
|
+
// We have 8 possible directions (N,NE,E,SE,S,SW,W,NW)
|
|
60
|
+
const direction = cornerHash & 7; // 0..7 → choose among 8 directions
|
|
61
|
+
const primary = direction < 4 ? x : y; // select primary component
|
|
62
|
+
const secondary = direction < 4 ? y : x; // select secondary component
|
|
63
|
+
// Assign signs based on low bits; compute dot product with (x,y)
|
|
64
|
+
const gradX = (direction & 1) === 0 ? 1 : -1; // primary sign
|
|
65
|
+
const gradY = (direction & 2) === 0 ? 1 : -1; // secondary sign
|
|
66
|
+
// return gradX * primary + gradY * secondary; // dot product with (x,y)
|
|
67
|
+
return gradX * primary + gradY * secondary;
|
|
68
|
+
}
|
|
69
|
+
// Linear interpolation between a and b with weight t
|
|
70
|
+
lerp(weight, start, end) {
|
|
71
|
+
return start + weight * (end - start);
|
|
72
|
+
}
|
|
73
|
+
// Raw Perlin value in roughly [-1, 1]
|
|
74
|
+
noise(x, y) {
|
|
75
|
+
// Locate integer cell (X,Y) and fractional offset inside it (xf,yf)
|
|
76
|
+
const cellX = Math.floor(x) & 255; // wrap to 0..255 for perm indexing
|
|
77
|
+
const cellY = Math.floor(y) & 255;
|
|
78
|
+
const offsetX = x - Math.floor(x); // 0..1
|
|
79
|
+
const offsetY = y - Math.floor(y);
|
|
80
|
+
// Compute eased weights along x and y
|
|
81
|
+
const fadedX = this.fade(offsetX);
|
|
82
|
+
const fadedY = this.fade(offsetY);
|
|
83
|
+
// Hash 4 corners of the cell
|
|
84
|
+
// (Find pseudo-random gradient indices for each corner using permutation table)
|
|
85
|
+
// grab a random cell indexed by cellX then use that value to index cellY
|
|
86
|
+
const cornerHash00 = this.perm[this.perm[cellX] + cellY];
|
|
87
|
+
const cornerHash01 = this.perm[this.perm[cellX] + cellY + 1];
|
|
88
|
+
const cornerHash10 = this.perm[this.perm[cellX + 1] + cellY];
|
|
89
|
+
const cornerHash11 = this.perm[this.perm[cellX + 1] + cellY + 1];
|
|
90
|
+
// Dot products of gradients with offsets, then bilinear interpolate with eased weights
|
|
91
|
+
const startBottom = this.grad(cornerHash00, offsetX, offsetY); // bottom-left corner
|
|
92
|
+
const endBottom = this.grad(cornerHash10, offsetX - 1, offsetY); // bottom-right corner
|
|
93
|
+
const interpolatedBottom = this.lerp(fadedX, startBottom, endBottom);
|
|
94
|
+
const startTop = this.grad(cornerHash01, offsetX, offsetY - 1); // top-left corner
|
|
95
|
+
const endTop = this.grad(cornerHash11, offsetX - 1, offsetY - 1); // top-right corner
|
|
96
|
+
const interpolatedTop = this.lerp(fadedX, startTop, endTop);
|
|
97
|
+
return this.lerp(fadedY, interpolatedBottom, interpolatedTop);
|
|
98
|
+
}
|
|
99
|
+
// Fractal Brownian Motion: sum octaves with increasing frequency and decaying amplitude,
|
|
100
|
+
// then normalize by total amplitude to keep overall range stable across octave counts.
|
|
101
|
+
fbm(x, y, octaves, persistence) {
|
|
102
|
+
let amplitude = 1; // starting amplitude
|
|
103
|
+
let frequency = 1; // starting frequency
|
|
104
|
+
let noiseSum = 0; // accumulated value
|
|
105
|
+
let totalAmplitude = 0; // accumulated amplitude for normalization
|
|
106
|
+
for (let octave = 0; octave < octaves; octave++) {
|
|
107
|
+
noiseSum += this.noise(x * frequency, y * frequency) * amplitude; // sample at current freq, scale by amp
|
|
108
|
+
totalAmplitude += amplitude; // track amplitude sum
|
|
109
|
+
amplitude *= persistence; // next octave is quieter
|
|
110
|
+
frequency *= 2; // and higher frequency
|
|
111
|
+
}
|
|
112
|
+
return noiseSum / totalAmplitude; // keep output roughly within [-1,1] regardless of octave count
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=Perlin2D.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Perlin2D.js","sourceRoot":"","sources":["../../src/math/Perlin2D.ts"],"names":[],"mappings":"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"}
|