Add basic cave generation
This commit is contained in:
parent
0653da20b2
commit
e21bda6201
7 changed files with 698 additions and 19 deletions
596
external/OpenSimplex3D.ts
vendored
Normal file
596
external/OpenSimplex3D.ts
vendored
Normal file
|
@ -0,0 +1,596 @@
|
||||||
|
// This is free and unencumbered software released into the public domain
|
||||||
|
|
||||||
|
import shuffleSeed from "./shuffle_seed";
|
||||||
|
|
||||||
|
const NORM_3D = 1.0 / 103.0;
|
||||||
|
const SQUISH_3D = (Math.sqrt(3 + 1) - 1) / 3;
|
||||||
|
const STRETCH_3D = (1 / Math.sqrt(3 + 1) - 1) / 3;
|
||||||
|
|
||||||
|
export type Noise3D = (x: number, y: number, z: number) => number;
|
||||||
|
|
||||||
|
interface Contribution3D {
|
||||||
|
dx: number;
|
||||||
|
dy: number;
|
||||||
|
dz: number;
|
||||||
|
next?: Contribution3D;
|
||||||
|
xsb: number;
|
||||||
|
ysb: number;
|
||||||
|
zsb: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function contribution3D(
|
||||||
|
multiplier: number,
|
||||||
|
xsb: number,
|
||||||
|
ysb: number,
|
||||||
|
zsb: number,
|
||||||
|
): Contribution3D {
|
||||||
|
return {
|
||||||
|
dx: -xsb - multiplier * SQUISH_3D,
|
||||||
|
dy: -ysb - multiplier * SQUISH_3D,
|
||||||
|
dz: -zsb - multiplier * SQUISH_3D,
|
||||||
|
xsb,
|
||||||
|
ysb,
|
||||||
|
zsb,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function makeNoise3D(clientSeed: number): Noise3D {
|
||||||
|
const contributions: Contribution3D[] = [];
|
||||||
|
for (let i = 0; i < p3D.length; i += 9) {
|
||||||
|
const baseSet = base3D[p3D[i]];
|
||||||
|
let previous: Contribution3D | null = null;
|
||||||
|
let current: Contribution3D | null = null;
|
||||||
|
for (let k = 0; k < baseSet.length; k += 4) {
|
||||||
|
current = contribution3D(
|
||||||
|
baseSet[k],
|
||||||
|
baseSet[k + 1],
|
||||||
|
baseSet[k + 2],
|
||||||
|
baseSet[k + 3],
|
||||||
|
);
|
||||||
|
if (previous === null) contributions[i / 9] = current;
|
||||||
|
else previous.next = current;
|
||||||
|
previous = current;
|
||||||
|
}
|
||||||
|
current!.next = contribution3D(
|
||||||
|
p3D[i + 1],
|
||||||
|
p3D[i + 2],
|
||||||
|
p3D[i + 3],
|
||||||
|
p3D[i + 4],
|
||||||
|
);
|
||||||
|
current!.next.next = contribution3D(
|
||||||
|
p3D[i + 5],
|
||||||
|
p3D[i + 6],
|
||||||
|
p3D[i + 7],
|
||||||
|
p3D[i + 8],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const lookup: Contribution3D[] = [];
|
||||||
|
for (let i = 0; i < lookupPairs3D.length; i += 2) {
|
||||||
|
lookup[lookupPairs3D[i]] = contributions[lookupPairs3D[i + 1]];
|
||||||
|
}
|
||||||
|
|
||||||
|
const perm = new Uint8Array(256);
|
||||||
|
const perm3D = new Uint8Array(256);
|
||||||
|
const source = new Uint8Array(256);
|
||||||
|
for (let i = 0; i < 256; i++) source[i] = i;
|
||||||
|
let seed = new Uint32Array(1);
|
||||||
|
seed[0] = clientSeed;
|
||||||
|
seed = shuffleSeed(shuffleSeed(shuffleSeed(seed)));
|
||||||
|
for (let i = 255; i >= 0; i--) {
|
||||||
|
seed = shuffleSeed(seed);
|
||||||
|
const r = new Uint32Array(1);
|
||||||
|
r[0] = (seed[0] + 31) % (i + 1);
|
||||||
|
if (r[0] < 0) r[0] += i + 1;
|
||||||
|
perm[i] = source[r[0]];
|
||||||
|
perm3D[i] = (perm[i] % 24) * 3;
|
||||||
|
source[r[0]] = source[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return (x: number, y: number, z: number): number => {
|
||||||
|
const stretchOffset = (x + y + z) * STRETCH_3D;
|
||||||
|
|
||||||
|
const xs = x + stretchOffset;
|
||||||
|
const ys = y + stretchOffset;
|
||||||
|
const zs = z + stretchOffset;
|
||||||
|
|
||||||
|
const xsb = Math.floor(xs);
|
||||||
|
const ysb = Math.floor(ys);
|
||||||
|
const zsb = Math.floor(zs);
|
||||||
|
|
||||||
|
const squishOffset = (xsb + ysb + zsb) * SQUISH_3D;
|
||||||
|
|
||||||
|
const dx0 = x - (xsb + squishOffset);
|
||||||
|
const dy0 = y - (ysb + squishOffset);
|
||||||
|
const dz0 = z - (zsb + squishOffset);
|
||||||
|
|
||||||
|
const xins = xs - xsb;
|
||||||
|
const yins = ys - ysb;
|
||||||
|
const zins = zs - zsb;
|
||||||
|
|
||||||
|
const inSum = xins + yins + zins;
|
||||||
|
const hash = (yins - zins + 1) |
|
||||||
|
((xins - yins + 1) << 1) |
|
||||||
|
((xins - zins + 1) << 2) |
|
||||||
|
(inSum << 3) |
|
||||||
|
((inSum + zins) << 5) |
|
||||||
|
((inSum + yins) << 7) |
|
||||||
|
((inSum + xins) << 9);
|
||||||
|
|
||||||
|
let value = 0;
|
||||||
|
|
||||||
|
for (
|
||||||
|
let c: Contribution3D | undefined = lookup[hash];
|
||||||
|
c !== undefined;
|
||||||
|
c = c.next
|
||||||
|
) {
|
||||||
|
const dx = dx0 + c.dx;
|
||||||
|
const dy = dy0 + c.dy;
|
||||||
|
const dz = dz0 + c.dz;
|
||||||
|
|
||||||
|
const attn = 2 - dx * dx - dy * dy - dz * dz;
|
||||||
|
if (attn > 0) {
|
||||||
|
const px = xsb + c.xsb;
|
||||||
|
const py = ysb + c.ysb;
|
||||||
|
const pz = zsb + c.zsb;
|
||||||
|
|
||||||
|
const indexPartA = perm[px & 0xff];
|
||||||
|
const indexPartB = perm[(indexPartA + py) & 0xff];
|
||||||
|
const index = perm3D[(indexPartB + pz) & 0xff];
|
||||||
|
|
||||||
|
const valuePart = gradients3D[index] * dx +
|
||||||
|
gradients3D[index + 1] * dy +
|
||||||
|
gradients3D[index + 2] * dz;
|
||||||
|
|
||||||
|
value += attn * attn * attn * attn * valuePart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value * NORM_3D;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const base3D = [
|
||||||
|
[0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1],
|
||||||
|
[2, 1, 1, 0, 2, 1, 0, 1, 2, 0, 1, 1, 3, 1, 1, 1],
|
||||||
|
[1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 2, 1, 1, 0, 2, 1, 0, 1, 2, 0, 1, 1],
|
||||||
|
];
|
||||||
|
|
||||||
|
const gradients3D = [
|
||||||
|
-11,
|
||||||
|
4,
|
||||||
|
4,
|
||||||
|
-4,
|
||||||
|
11,
|
||||||
|
4,
|
||||||
|
-4,
|
||||||
|
4,
|
||||||
|
11,
|
||||||
|
11,
|
||||||
|
4,
|
||||||
|
4,
|
||||||
|
4,
|
||||||
|
11,
|
||||||
|
4,
|
||||||
|
4,
|
||||||
|
4,
|
||||||
|
11,
|
||||||
|
-11,
|
||||||
|
-4,
|
||||||
|
4,
|
||||||
|
-4,
|
||||||
|
-11,
|
||||||
|
4,
|
||||||
|
-4,
|
||||||
|
-4,
|
||||||
|
11,
|
||||||
|
11,
|
||||||
|
-4,
|
||||||
|
4,
|
||||||
|
4,
|
||||||
|
-11,
|
||||||
|
4,
|
||||||
|
4,
|
||||||
|
-4,
|
||||||
|
11,
|
||||||
|
-11,
|
||||||
|
4,
|
||||||
|
-4,
|
||||||
|
-4,
|
||||||
|
11,
|
||||||
|
-4,
|
||||||
|
-4,
|
||||||
|
4,
|
||||||
|
-11,
|
||||||
|
11,
|
||||||
|
4,
|
||||||
|
-4,
|
||||||
|
4,
|
||||||
|
11,
|
||||||
|
-4,
|
||||||
|
4,
|
||||||
|
4,
|
||||||
|
-11,
|
||||||
|
-11,
|
||||||
|
-4,
|
||||||
|
-4,
|
||||||
|
-4,
|
||||||
|
-11,
|
||||||
|
-4,
|
||||||
|
-4,
|
||||||
|
-4,
|
||||||
|
-11,
|
||||||
|
11,
|
||||||
|
-4,
|
||||||
|
-4,
|
||||||
|
4,
|
||||||
|
-11,
|
||||||
|
-4,
|
||||||
|
4,
|
||||||
|
-4,
|
||||||
|
-11,
|
||||||
|
];
|
||||||
|
|
||||||
|
const lookupPairs3D = [
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
5,
|
||||||
|
1,
|
||||||
|
6,
|
||||||
|
0,
|
||||||
|
7,
|
||||||
|
0,
|
||||||
|
32,
|
||||||
|
2,
|
||||||
|
34,
|
||||||
|
2,
|
||||||
|
129,
|
||||||
|
1,
|
||||||
|
133,
|
||||||
|
1,
|
||||||
|
160,
|
||||||
|
5,
|
||||||
|
161,
|
||||||
|
5,
|
||||||
|
518,
|
||||||
|
0,
|
||||||
|
519,
|
||||||
|
0,
|
||||||
|
546,
|
||||||
|
4,
|
||||||
|
550,
|
||||||
|
4,
|
||||||
|
645,
|
||||||
|
3,
|
||||||
|
647,
|
||||||
|
3,
|
||||||
|
672,
|
||||||
|
5,
|
||||||
|
673,
|
||||||
|
5,
|
||||||
|
674,
|
||||||
|
4,
|
||||||
|
677,
|
||||||
|
3,
|
||||||
|
678,
|
||||||
|
4,
|
||||||
|
679,
|
||||||
|
3,
|
||||||
|
680,
|
||||||
|
13,
|
||||||
|
681,
|
||||||
|
13,
|
||||||
|
682,
|
||||||
|
12,
|
||||||
|
685,
|
||||||
|
14,
|
||||||
|
686,
|
||||||
|
12,
|
||||||
|
687,
|
||||||
|
14,
|
||||||
|
712,
|
||||||
|
20,
|
||||||
|
714,
|
||||||
|
18,
|
||||||
|
809,
|
||||||
|
21,
|
||||||
|
813,
|
||||||
|
23,
|
||||||
|
840,
|
||||||
|
20,
|
||||||
|
841,
|
||||||
|
21,
|
||||||
|
1198,
|
||||||
|
19,
|
||||||
|
1199,
|
||||||
|
22,
|
||||||
|
1226,
|
||||||
|
18,
|
||||||
|
1230,
|
||||||
|
19,
|
||||||
|
1325,
|
||||||
|
23,
|
||||||
|
1327,
|
||||||
|
22,
|
||||||
|
1352,
|
||||||
|
15,
|
||||||
|
1353,
|
||||||
|
17,
|
||||||
|
1354,
|
||||||
|
15,
|
||||||
|
1357,
|
||||||
|
17,
|
||||||
|
1358,
|
||||||
|
16,
|
||||||
|
1359,
|
||||||
|
16,
|
||||||
|
1360,
|
||||||
|
11,
|
||||||
|
1361,
|
||||||
|
10,
|
||||||
|
1362,
|
||||||
|
11,
|
||||||
|
1365,
|
||||||
|
10,
|
||||||
|
1366,
|
||||||
|
9,
|
||||||
|
1367,
|
||||||
|
9,
|
||||||
|
1392,
|
||||||
|
11,
|
||||||
|
1394,
|
||||||
|
11,
|
||||||
|
1489,
|
||||||
|
10,
|
||||||
|
1493,
|
||||||
|
10,
|
||||||
|
1520,
|
||||||
|
8,
|
||||||
|
1521,
|
||||||
|
8,
|
||||||
|
1878,
|
||||||
|
9,
|
||||||
|
1879,
|
||||||
|
9,
|
||||||
|
1906,
|
||||||
|
7,
|
||||||
|
1910,
|
||||||
|
7,
|
||||||
|
2005,
|
||||||
|
6,
|
||||||
|
2007,
|
||||||
|
6,
|
||||||
|
2032,
|
||||||
|
8,
|
||||||
|
2033,
|
||||||
|
8,
|
||||||
|
2034,
|
||||||
|
7,
|
||||||
|
2037,
|
||||||
|
6,
|
||||||
|
2038,
|
||||||
|
7,
|
||||||
|
2039,
|
||||||
|
6,
|
||||||
|
];
|
||||||
|
|
||||||
|
const p3D = [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
-1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
-1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
-1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
-1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
3,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
3,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
3,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
3,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
3,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
3,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
-1,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
-1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
-1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
-1,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
-1,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
-1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
-1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
-1,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
-1,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
];
|
|
@ -40,6 +40,16 @@ export class Chunk {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getTopBlockY(x:number, z:number) {
|
||||||
|
let castY = this.MAX_HEIGHT;
|
||||||
|
while (castY-- > 0) {
|
||||||
|
if (this.getBlockId(x, castY, z) !== 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return castY;
|
||||||
|
}
|
||||||
|
|
||||||
public calculateLighting() {
|
public calculateLighting() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,12 @@ export class MPClient {
|
||||||
const consoleMessage = `[CONSOLE] ${message.slice(1, message.length).join(" ")}`;
|
const consoleMessage = `[CONSOLE] ${message.slice(1, message.length).join(" ")}`;
|
||||||
Console.printChat(consoleMessage);
|
Console.printChat(consoleMessage);
|
||||||
this.mcServer.sendToAllClients(new PacketChat(consoleMessage).writeData());
|
this.mcServer.sendToAllClients(new PacketChat(consoleMessage).writeData());
|
||||||
|
} else if (message[0] === "/top") {
|
||||||
|
// TODO: Figure out why this is broken
|
||||||
|
packet.message = `Woosh!`;
|
||||||
|
const topBlock = this.entity.world.getChunk(this.entity.x >> 4, this.entity.z >> 4).getTopBlockY(this.entity.x & 0xf, this.entity.z & 0xf);
|
||||||
|
console.log(topBlock);
|
||||||
|
this.send(new PacketPlayerPositionLook(this.entity.x, topBlock, topBlock + 0.62, this.entity.z, this.entity.yaw, this.entity.pitch, false).writeData());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet.message !== "") {
|
if (packet.message !== "") {
|
||||||
|
|
|
@ -86,9 +86,9 @@ export class WorldSaveManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public writeChunkToDisk(chunk:Chunk) {
|
public writeChunkToDisk(chunk:Chunk) {
|
||||||
/*return new Promise<boolean>((resolve, reject) => {
|
return new Promise<boolean>((resolve, reject) => {
|
||||||
resolve(true);
|
resolve(true);
|
||||||
});*/
|
});
|
||||||
return new Promise<boolean>((resolve, reject) => {
|
return new Promise<boolean>((resolve, reject) => {
|
||||||
const saveType = this.config.saveCompression;
|
const saveType = this.config.saveCompression;
|
||||||
const chunkFileWriter = new Writer(10);
|
const chunkFileWriter = new Writer(10);
|
||||||
|
|
|
@ -26,6 +26,8 @@ export class Block {
|
||||||
|
|
||||||
static readonly waterStill = new Block(9);
|
static readonly waterStill = new Block(9);
|
||||||
|
|
||||||
|
static readonly lavaStill = new Block(11);
|
||||||
|
|
||||||
static readonly sand = new Block(12);
|
static readonly sand = new Block(12);
|
||||||
static readonly gravel = new Block(13);
|
static readonly gravel = new Block(13);
|
||||||
|
|
||||||
|
@ -34,5 +36,8 @@ export class Block {
|
||||||
|
|
||||||
static readonly tallGrass = new Block(31);
|
static readonly tallGrass = new Block(31);
|
||||||
|
|
||||||
|
static readonly flowerDandelion = new Block(37);
|
||||||
|
static readonly flowerRose = new Block(38);
|
||||||
|
|
||||||
static readonly clay = new Block(82);
|
static readonly clay = new Block(82);
|
||||||
}
|
}
|
13
server/entities/Item.ts
Normal file
13
server/entities/Item.ts
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import { World } from "../World";
|
||||||
|
import { ItemStack } from "../containers/ItemStack";
|
||||||
|
import { Entity } from "./Entity";
|
||||||
|
|
||||||
|
export class EntityItem extends Entity {
|
||||||
|
public age:number;
|
||||||
|
|
||||||
|
public constructor(world:World, x:number, y:number, z:number, itemStack:ItemStack) {
|
||||||
|
super(world);
|
||||||
|
this.age = 0;
|
||||||
|
this.health = 5;
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ import { Block } from "../blocks/Block";
|
||||||
import { Chunk } from "../Chunk";
|
import { Chunk } from "../Chunk";
|
||||||
import { IGenerator } from "./IGenerator";
|
import { IGenerator } from "./IGenerator";
|
||||||
import { Noise2D, makeNoise2D } from "../../external/OpenSimplex2D";
|
import { Noise2D, makeNoise2D } from "../../external/OpenSimplex2D";
|
||||||
|
import { Noise3D, makeNoise3D } from "../../external/OpenSimplex3D";
|
||||||
import { QueuedBlockUpdate } from "../queuedUpdateTypes/BlockUpdate";
|
import { QueuedBlockUpdate } from "../queuedUpdateTypes/BlockUpdate";
|
||||||
|
|
||||||
export class HillyGenerator implements IGenerator {
|
export class HillyGenerator implements IGenerator {
|
||||||
|
@ -16,33 +17,53 @@ export class HillyGenerator implements IGenerator {
|
||||||
private generator5:Noise2D;
|
private generator5:Noise2D;
|
||||||
private generator6:Noise2D;
|
private generator6:Noise2D;
|
||||||
private oceanGenerator:Noise2D;
|
private oceanGenerator:Noise2D;
|
||||||
private mountainGenerator:Noise2D;
|
private hillGenerator:Noise2D;
|
||||||
|
|
||||||
|
private caveGenerator1:Noise3D;
|
||||||
|
private caveGenerator2:Noise3D;
|
||||||
|
private caveGenerator3:Noise3D;
|
||||||
|
private caveGenerator4:Noise3D;
|
||||||
|
|
||||||
private underwaterGravelGenerator:Noise2D;
|
private underwaterGravelGenerator:Noise2D;
|
||||||
private underwaterSandGenerator:Noise2D;
|
private underwaterSandGenerator:Noise2D;
|
||||||
private underwaterClayGenerator:Noise2D;
|
private underwaterClayGenerator:Noise2D;
|
||||||
|
private flowerGenerator:Noise2D;
|
||||||
|
|
||||||
public constructor(seed:number) {
|
public constructor(seed:number) {
|
||||||
this.seed = seed;
|
this.seed = seed;
|
||||||
this.seedGenerator = this.mulberry32(this.seed);
|
this.seedGenerator = this.mulberry32(this.seed);
|
||||||
|
|
||||||
this.generator = this.createGenerator();
|
this.generator = this.createGenerator2D();
|
||||||
this.generator1 = this.createGenerator();
|
this.generator1 = this.createGenerator2D();
|
||||||
this.generator2 = this.createGenerator();
|
this.generator2 = this.createGenerator2D();
|
||||||
this.generator3 = this.createGenerator();
|
this.generator3 = this.createGenerator2D();
|
||||||
this.generator4 = this.createGenerator();
|
this.generator4 = this.createGenerator2D();
|
||||||
this.generator5 = this.createGenerator();
|
this.generator5 = this.createGenerator2D();
|
||||||
this.generator6 = this.createGenerator();
|
this.generator6 = this.createGenerator2D();
|
||||||
this.oceanGenerator = this.createGenerator();
|
this.oceanGenerator = this.createGenerator2D();
|
||||||
this.mountainGenerator = this.createGenerator();
|
this.hillGenerator = this.createGenerator2D();
|
||||||
this.underwaterGravelGenerator = this.createGenerator();
|
|
||||||
this.underwaterSandGenerator = this.createGenerator();
|
this.caveGenerator1 = this.createGenerator3D();
|
||||||
this.underwaterClayGenerator = this.createGenerator();
|
this.caveGenerator2 = this.createGenerator3D();
|
||||||
|
this.caveGenerator3 = this.createGenerator3D();
|
||||||
|
this.caveGenerator4 = this.createGenerator3D();
|
||||||
|
|
||||||
|
this.underwaterGravelGenerator = this.createGenerator2D();
|
||||||
|
this.underwaterSandGenerator = this.createGenerator2D();
|
||||||
|
this.underwaterClayGenerator = this.createGenerator2D();
|
||||||
|
this.flowerGenerator = this.createGenerator2D();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private createGenerator() {
|
private createGenerator2D() {
|
||||||
return makeNoise2D(this.seedGenerator() * Number.MAX_SAFE_INTEGER);
|
return makeNoise2D(this.seedGenerator() * Number.MAX_SAFE_INTEGER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private createGenerator3D() {
|
||||||
|
return makeNoise3D(this.seedGenerator() * Number.MAX_SAFE_INTEGER);
|
||||||
|
}
|
||||||
|
|
||||||
// This is soooo much faster than using Math.round in here
|
// This is soooo much faster than using Math.round in here
|
||||||
private fastRound(num:number) {
|
private fastRound(num:number) {
|
||||||
return num >= 0.5 ? (num | 0) + 1 : num | 0;
|
return num >= 0.5 ? (num | 0) + 1 : num | 0;
|
||||||
|
@ -62,6 +83,7 @@ export class HillyGenerator implements IGenerator {
|
||||||
public generate(chunk:Chunk) {
|
public generate(chunk:Chunk) {
|
||||||
const treeRNG = this.mulberry32(this.seed + chunk.x + chunk.z);
|
const treeRNG = this.mulberry32(this.seed + chunk.x + chunk.z);
|
||||||
const grassRNG = this.mulberry32(this.seed + chunk.x + chunk.z);
|
const grassRNG = this.mulberry32(this.seed + chunk.x + chunk.z);
|
||||||
|
const flowerRNG = this.mulberry32(this.seed + chunk.x + chunk.z);
|
||||||
|
|
||||||
let colY = 0, colDirtMin = 0, colWaterY = 0, orgColY = 0;
|
let colY = 0, colDirtMin = 0, colWaterY = 0, orgColY = 0;
|
||||||
for (let x = 0; x < 16; x++) {
|
for (let x = 0; x < 16; x++) {
|
||||||
|
@ -76,7 +98,7 @@ export class HillyGenerator implements IGenerator {
|
||||||
this.generator5((chunk.x * 16 + x) / 10, (chunk.z * 16 + z) / 10) * 10 +
|
this.generator5((chunk.x * 16 + x) / 10, (chunk.z * 16 + z) / 10) * 10 +
|
||||||
this.generator6((chunk.x * 16 + x) / 16, (chunk.z * 16 + z) / 16) * 16 +
|
this.generator6((chunk.x * 16 + x) / 16, (chunk.z * 16 + z) / 16) * 16 +
|
||||||
oceanValue +
|
oceanValue +
|
||||||
(Math.max(this.mountainGenerator((chunk.x * 16 + x) / 128, (chunk.z * 16 + z) / 128), 0) * 50 + Math.min(oceanValue, 0))
|
(Math.max(this.hillGenerator((chunk.x * 16 + x) / 128, (chunk.z * 16 + z) / 128), 0) * 50 + Math.min(oceanValue, 0))
|
||||||
) / 9);
|
) / 9);
|
||||||
colDirtMin = colY - 2;
|
colDirtMin = colY - 2;
|
||||||
const sandNoise = this.underwaterSandGenerator((chunk.x * 16 + x) / 16, (chunk.z * 16 + z) / 16);
|
const sandNoise = this.underwaterSandGenerator((chunk.x * 16 + x) / 16, (chunk.z * 16 + z) / 16);
|
||||||
|
@ -86,6 +108,7 @@ export class HillyGenerator implements IGenerator {
|
||||||
chunk.setBlock(Block.grass.blockId, x, colY, z);
|
chunk.setBlock(Block.grass.blockId, x, colY, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let caveY = colY + 1;
|
||||||
while (colY-- > 0) {
|
while (colY-- > 0) {
|
||||||
if (colY >= colDirtMin) {
|
if (colY >= colDirtMin) {
|
||||||
chunk.setBlock(Block.dirt.blockId, x, colY, z);
|
chunk.setBlock(Block.dirt.blockId, x, colY, z);
|
||||||
|
@ -113,6 +136,22 @@ export class HillyGenerator implements IGenerator {
|
||||||
chunk.setBlock(Block.waterStill.blockId, x, colWaterY, z);
|
chunk.setBlock(Block.waterStill.blockId, x, colWaterY, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
while (caveY-- > 1) {
|
||||||
|
if (
|
||||||
|
this.caveGenerator1((chunk.x * 16 + x) / 16, caveY / 16, (chunk.z * 16 + z) / 16) > 0.45 ||
|
||||||
|
this.caveGenerator2((chunk.x * 16 + x) / 8, caveY / 8, (chunk.z * 16 + z) / 8) > 0.6 ||
|
||||||
|
this.caveGenerator3((chunk.x * 16 + x) / 256, caveY / 256, (chunk.z * 16 + z) / 256) > 0.6 ||
|
||||||
|
this.caveGenerator4((chunk.x * 16 + x) / 128, caveY / 128, (chunk.z * 16 + z) / 128) > 0.6
|
||||||
|
) {
|
||||||
|
if (caveY <= 3) {
|
||||||
|
chunk.setBlock(Block.lavaStill.blockId, x, caveY, z);
|
||||||
|
} else {
|
||||||
|
chunk.setBlock(0, x, caveY, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const queuedChunkBlocks = chunk.world.queuedChunkBlocks;
|
const queuedChunkBlocks = chunk.world.queuedChunkBlocks;
|
||||||
if (queuedChunkBlocks.length > 0) {
|
if (queuedChunkBlocks.length > 0) {
|
||||||
const thisCoordPair = Chunk.CreateCoordPair(chunk.x, chunk.z);
|
const thisCoordPair = Chunk.CreateCoordPair(chunk.x, chunk.z);
|
||||||
|
@ -125,9 +164,19 @@ export class HillyGenerator implements IGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grassRNG() > 0.9 && chunk.getBlockId(x, orgColY, z) === Block.grass.blockId) {
|
// Grass and flowers
|
||||||
|
if (chunk.getBlockId(x, orgColY, z) === Block.grass.blockId) {
|
||||||
|
if (grassRNG() > 0.9) {
|
||||||
chunk.setBlockWithMetadata(Block.tallGrass.blockId, 1, x, orgColY + 1, z);
|
chunk.setBlockWithMetadata(Block.tallGrass.blockId, 1, x, orgColY + 1, z);
|
||||||
|
} else if (this.flowerGenerator((chunk.x * 16 + x) / 16, (chunk.z * 16 + z) / 16) > 0.5 && flowerRNG() > 0.9) {
|
||||||
|
if (flowerRNG() > 0.4) {
|
||||||
|
chunk.setBlockWithMetadata(Block.flowerRose.blockId, 1, x, orgColY + 1, z);
|
||||||
|
} else {
|
||||||
|
chunk.setBlockWithMetadata(Block.flowerDandelion.blockId, 1, x, orgColY + 1, z);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: Move trees to it's own generator
|
// TODO: Move trees to it's own generator
|
||||||
if (chunk.getBlockId(x, orgColY + 1, z) !== Block.waterStill.blockId && chunk.getBlockId(x, orgColY, z) === Block.grass.blockId && treeRNG() > 0.995) {
|
if (chunk.getBlockId(x, orgColY + 1, z) !== Block.waterStill.blockId && chunk.getBlockId(x, orgColY, z) === Block.grass.blockId && treeRNG() > 0.995) {
|
||||||
|
|
Loading…
Reference in a new issue