WIP: Lighting
This commit is contained in:
parent
ad1c402d84
commit
2aedd81baa
8 changed files with 145 additions and 42 deletions
|
@ -48,6 +48,10 @@ export class FunkyArray<T, TT> {
|
||||||
return this.items.get(key);
|
return this.items.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public has(key:T) : boolean {
|
||||||
|
return this.itemKeys.includes(key);
|
||||||
|
}
|
||||||
|
|
||||||
public get keys() : Array<T> {
|
public get keys() : Array<T> {
|
||||||
return this.itemKeys;
|
return this.itemKeys;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { FunkyArray } from "../funkyArray";
|
import { FunkyArray } from "../funkyArray";
|
||||||
import { NibbleArray } from "../nibbleArray";
|
import { NibbleArray } from "../nibbleArray";
|
||||||
|
import { Block } from "./blocks/Block";
|
||||||
import { Player } from "./entities/Player";
|
import { Player } from "./entities/Player";
|
||||||
import { QueuedBlockUpdate } from "./queuedUpdateTypes/BlockUpdate";
|
import { QueuedBlockUpdate } from "./queuedUpdateTypes/BlockUpdate";
|
||||||
import { World } from "./World";
|
import { World } from "./World";
|
||||||
|
@ -16,26 +17,39 @@ export class Chunk {
|
||||||
|
|
||||||
private blocks:Uint8Array;
|
private blocks:Uint8Array;
|
||||||
private metadata:NibbleArray;
|
private metadata:NibbleArray;
|
||||||
|
public skyLight:NibbleArray;
|
||||||
|
public blockLight:NibbleArray;
|
||||||
|
|
||||||
public static CreateCoordPair(x:number, z:number) {
|
public static CreateCoordPair(x:number, z:number) {
|
||||||
return (x >= 0 ? 0 : 2147483648) | (x & 0x7fff) << 16 | (z >= 0 ? 0 : 0x8000) | z & 0x7fff;
|
return (x >= 0 ? 0 : 2147483648) | (x & 0x7fff) << 16 | (z >= 0 ? 0 : 0x8000) | z & 0x7fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
public constructor(world:World, x:number, z:number, generateOrBlockData?:boolean|Uint8Array, metadata?:Uint8Array) {
|
public constructor(world:World, x:number, z:number, generateOrBlockData?:boolean|Uint8Array, metadata?:Uint8Array, blockLight?:Uint8Array, skyLight?:Uint8Array) {
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.z = z;
|
this.z = z;
|
||||||
this.playersInChunk = new FunkyArray<number, Player>();
|
this.playersInChunk = new FunkyArray<number, Player>();
|
||||||
|
|
||||||
if (generateOrBlockData instanceof Uint8Array && metadata instanceof Uint8Array) {
|
if (generateOrBlockData instanceof Uint8Array && metadata instanceof Uint8Array && blockLight instanceof Uint8Array && skyLight instanceof Uint8Array) {
|
||||||
this.blocks = new Uint8Array(generateOrBlockData);
|
this.blocks = new Uint8Array(generateOrBlockData);
|
||||||
this.metadata = new NibbleArray(metadata);
|
this.metadata = new NibbleArray(metadata);
|
||||||
|
this.skyLight = new NibbleArray(blockLight);
|
||||||
|
this.blockLight = new NibbleArray(skyLight);
|
||||||
|
} else if (generateOrBlockData instanceof Uint8Array && metadata instanceof Uint8Array && !(blockLight instanceof Uint8Array) && !(skyLight instanceof Uint8Array)) {
|
||||||
|
this.blocks = new Uint8Array(generateOrBlockData);
|
||||||
|
this.metadata = new NibbleArray(metadata);
|
||||||
|
this.skyLight = new NibbleArray(16 * 16 * this.MAX_HEIGHT);
|
||||||
|
this.blockLight = new NibbleArray(16 * 16 * this.MAX_HEIGHT);
|
||||||
|
this.calculateLighting();
|
||||||
} else {
|
} else {
|
||||||
this.blocks = new Uint8Array(16 * 16 * this.MAX_HEIGHT);
|
this.blocks = new Uint8Array(16 * 16 * this.MAX_HEIGHT);
|
||||||
this.metadata = new NibbleArray(16 * 16 * this.MAX_HEIGHT);
|
this.metadata = new NibbleArray(16 * 16 * this.MAX_HEIGHT);
|
||||||
|
this.skyLight = new NibbleArray(16 * 16 * this.MAX_HEIGHT);
|
||||||
|
this.blockLight = new NibbleArray(16 * 16 * this.MAX_HEIGHT);
|
||||||
|
|
||||||
if (typeof(generateOrBlockData) === "boolean" && generateOrBlockData) {
|
if (typeof(generateOrBlockData) === "boolean" && generateOrBlockData) {
|
||||||
this.world.generator.generate(this);
|
this.world.generator.generate(this);
|
||||||
|
this.calculateLighting();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,7 +65,32 @@ export class Chunk {
|
||||||
}
|
}
|
||||||
|
|
||||||
public calculateLighting() {
|
public calculateLighting() {
|
||||||
|
let blockId = 0;
|
||||||
|
for (let y = 0; y < 128; y++) {
|
||||||
|
let colLight = 255;
|
||||||
|
for (let x = 0; x < 16; x++) {
|
||||||
|
for (let z = 0; z < 16; z++) {
|
||||||
|
blockId = this.getBlockId(x, y, z);
|
||||||
|
if (blockId == 0) {
|
||||||
|
if (colLight <= 0) {
|
||||||
|
this.setBlockLight(0, x, y, z);
|
||||||
|
this.setSkyLight(0, x, y, z);
|
||||||
|
} else {
|
||||||
|
this.setBlockLight(Math.round((colLight / 255) * 15), x, y, z);
|
||||||
|
this.setSkyLight(Math.round((colLight / 255) * 15), x, y, z);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colLight <= 0) {
|
||||||
|
this.setBlockLight(0, x, y, z);
|
||||||
|
} else {
|
||||||
|
this.setBlockLight(Math.round((colLight / 255) * 15), x, y, z);
|
||||||
|
colLight -= (255 - Block.blocks[blockId].lightPassage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public queueBlockUpdateForOuterChunkBlock(blockId:number, metadata:number, x:number, y:number, z:number) {
|
public queueBlockUpdateForOuterChunkBlock(blockId:number, metadata:number, x:number, y:number, z:number) {
|
||||||
|
@ -91,10 +130,38 @@ export class Chunk {
|
||||||
return this.metadata.get(x << 11 | z << 7 | y);
|
return this.metadata.get(x << 11 | z << 7 | y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getBlockLight(x:number, y:number, z:number) {
|
||||||
|
return this.blockLight.get(x << 11 | z << 7 | y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public setBlockLight(value:number, x:number, y:number, z:number) {
|
||||||
|
return this.blockLight.set(x << 11 | z << 7 | y, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getSkyLight(x:number, y:number, z:number) {
|
||||||
|
return this.skyLight.get(x << 11 | z << 7 | y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public setSkyLight(value:number, x:number, y:number, z:number) {
|
||||||
|
return this.skyLight.set(x << 11 | z << 7 | y, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getBlockBuffer() {
|
||||||
|
return Buffer.from(this.blocks);
|
||||||
|
}
|
||||||
|
|
||||||
public getMetadataBuffer() {
|
public getMetadataBuffer() {
|
||||||
return this.metadata.toBuffer();
|
return this.metadata.toBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getBlockLightBuffer() {
|
||||||
|
return this.metadata.toBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public getSkyLightBuffer() {
|
||||||
|
return this.metadata.toBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
public getData() {
|
public getData() {
|
||||||
return this.blocks;
|
return this.blocks;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ export class World {
|
||||||
public removeEntity(entity:IEntity) {
|
public removeEntity(entity:IEntity) {
|
||||||
if (entity instanceof Player) {
|
if (entity instanceof Player) {
|
||||||
for (const coordPair of entity.loadedChunks) {
|
for (const coordPair of entity.loadedChunks) {
|
||||||
|
if (this.chunkExists(coordPair)) {
|
||||||
const chunk = this.getChunkByCoordPair(coordPair);
|
const chunk = this.getChunkByCoordPair(coordPair);
|
||||||
chunk.playersInChunk.remove(entity.entityId);
|
chunk.playersInChunk.remove(entity.entityId);
|
||||||
|
|
||||||
|
@ -52,6 +53,7 @@ export class World {
|
||||||
this.unloadChunk(coordPair);
|
this.unloadChunk(coordPair);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
this.players.remove(entity.entityId);
|
this.players.remove(entity.entityId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +61,14 @@ export class World {
|
||||||
// TODO: Inform clients about entity removal
|
// TODO: Inform clients about entity removal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public chunkExists(coordPairOrX:number, chunkZ?:number) {
|
||||||
|
if (typeof(coordPairOrX) === "number" && typeof(chunkZ) === "number") {
|
||||||
|
return this.chunks.has(Chunk.CreateCoordPair(coordPairOrX, chunkZ));
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.chunks.has(coordPairOrX);
|
||||||
|
}
|
||||||
|
|
||||||
public getChunk(x:number, z:number, generate:boolean = true) {
|
public getChunk(x:number, z:number, generate:boolean = true) {
|
||||||
const coordPair = Chunk.CreateCoordPair(x, z);
|
const coordPair = Chunk.CreateCoordPair(x, z);
|
||||||
const existingChunk = this.chunks.get(coordPair);
|
const existingChunk = this.chunks.get(coordPair);
|
||||||
|
@ -206,12 +216,15 @@ export class World {
|
||||||
if (entity instanceof Player) {
|
if (entity instanceof Player) {
|
||||||
if (entity.justUnloaded.length > 0) {
|
if (entity.justUnloaded.length > 0) {
|
||||||
for (const coordPair of entity.justUnloaded) {
|
for (const coordPair of entity.justUnloaded) {
|
||||||
|
if (this.chunks.get(coordPair) != undefined)
|
||||||
|
{
|
||||||
const chunkToUnload = this.getChunkByCoordPair(coordPair);
|
const chunkToUnload = this.getChunkByCoordPair(coordPair);
|
||||||
chunkToUnload.playersInChunk.remove(entity.entityId);
|
chunkToUnload.playersInChunk.remove(entity.entityId);
|
||||||
if (!chunkToUnload.forceLoaded && chunkToUnload.playersInChunk.length === 0) {
|
if (!chunkToUnload.forceLoaded && chunkToUnload.playersInChunk.length === 0) {
|
||||||
this.unloadChunk(coordPair);
|
this.unloadChunk(coordPair);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
entity.justUnloaded = new Array<number>();
|
entity.justUnloaded = new Array<number>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,13 +86,11 @@ export class WorldSaveManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public writeChunkToDisk(chunk:Chunk) {
|
public writeChunkToDisk(chunk:Chunk) {
|
||||||
/*return new Promise<boolean>((resolve, reject) => {
|
|
||||||
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);
|
||||||
chunkFileWriter.writeUByte(0xFC); // Chunk File Magic
|
chunkFileWriter.writeUByte(0xFC); // Chunk File Magic
|
||||||
|
// TODO: Change to 1 when lighting actually works
|
||||||
chunkFileWriter.writeUByte(0); // File Version
|
chunkFileWriter.writeUByte(0); // File Version
|
||||||
chunkFileWriter.writeUByte(saveType); // Save compression type
|
chunkFileWriter.writeUByte(saveType); // Save compression type
|
||||||
chunkFileWriter.writeUByte(16); // Chunk X
|
chunkFileWriter.writeUByte(16); // Chunk X
|
||||||
|
@ -101,13 +99,15 @@ export class WorldSaveManager {
|
||||||
|
|
||||||
const chunkData = new Writer()
|
const chunkData = new Writer()
|
||||||
.writeBuffer(Buffer.from(chunk.getData()))
|
.writeBuffer(Buffer.from(chunk.getData()))
|
||||||
.writeBuffer(chunk.getMetadataBuffer()).toBuffer();
|
.writeBuffer(chunk.getMetadataBuffer()).toBuffer()
|
||||||
|
//.writeBuffer(chunk.getBlockLightBuffer())
|
||||||
|
//.writeBuffer(chunk.getSkyLightBuffer()).toBuffer();
|
||||||
|
|
||||||
if (saveType === SaveCompressionType.NONE) {
|
if (saveType === SaveCompressionType.NONE) {
|
||||||
chunkFileWriter.writeInt(chunkData.length); // Data length
|
chunkFileWriter.writeInt(chunkData.length); // Data length
|
||||||
chunkFileWriter.writeBuffer(chunkData); // Chunk data
|
chunkFileWriter.writeBuffer(chunkData); // Chunk data
|
||||||
|
|
||||||
writeFile(`${this.worldChunksFolderPath}/${chunk.x},${chunk.z}.hwc`, chunkFileWriter.toBuffer(), () => {
|
writeFile(`${this.worldChunksFolderPath}/${Chunk.CreateCoordPair(chunk.x, chunk.z)}.hwc`, chunkFileWriter.toBuffer(), () => {
|
||||||
const cPair = Chunk.CreateCoordPair(chunk.x, chunk.z);
|
const cPair = Chunk.CreateCoordPair(chunk.x, chunk.z);
|
||||||
if (!this.chunksOnDisk.includes(cPair)) {
|
if (!this.chunksOnDisk.includes(cPair)) {
|
||||||
this.chunksOnDisk.push(cPair);
|
this.chunksOnDisk.push(cPair);
|
||||||
|
@ -124,7 +124,7 @@ export class WorldSaveManager {
|
||||||
chunkFileWriter.writeInt(data.length);
|
chunkFileWriter.writeInt(data.length);
|
||||||
chunkFileWriter.writeBuffer(data);
|
chunkFileWriter.writeBuffer(data);
|
||||||
|
|
||||||
writeFile(`${this.worldChunksFolderPath}/${chunk.x},${chunk.z}.hwc`, chunkFileWriter.toBuffer(), () => {
|
writeFile(`${this.worldChunksFolderPath}/${Chunk.CreateCoordPair(chunk.x, chunk.z)}.hwc`, chunkFileWriter.toBuffer(), () => {
|
||||||
const cPair = Chunk.CreateCoordPair(chunk.x, chunk.z);
|
const cPair = Chunk.CreateCoordPair(chunk.x, chunk.z);
|
||||||
if (!this.chunksOnDisk.includes(cPair)) {
|
if (!this.chunksOnDisk.includes(cPair)) {
|
||||||
this.chunksOnDisk.push(cPair);
|
this.chunksOnDisk.push(cPair);
|
||||||
|
@ -141,7 +141,7 @@ export class WorldSaveManager {
|
||||||
|
|
||||||
readChunkFromDisk(world:World, x:number, z:number) {
|
readChunkFromDisk(world:World, x:number, z:number) {
|
||||||
return new Promise<Chunk>((resolve, reject) => {
|
return new Promise<Chunk>((resolve, reject) => {
|
||||||
readFile(`${this.worldChunksFolderPath}/${x},${z}.hwc`, (err, data) => {
|
readFile(`${this.worldChunksFolderPath}/${Chunk.CreateCoordPair(x, z)}.hwc`, (err, data) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return reject(err);
|
return reject(err);
|
||||||
}
|
}
|
||||||
|
@ -177,6 +177,29 @@ export class WorldSaveManager {
|
||||||
resolve(chunk);
|
resolve(chunk);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
} else if (fileVersion === 1) {
|
||||||
|
const saveCompressionType:SaveCompressionType = chunkFileReader.readUByte();
|
||||||
|
const chunkX = chunkFileReader.readUByte();
|
||||||
|
const chunkY = chunkFileReader.readUByte();
|
||||||
|
const chunkZ = chunkFileReader.readUByte();
|
||||||
|
const totalByteSize = chunkX * chunkZ * chunkY;
|
||||||
|
|
||||||
|
const contentLength = chunkFileReader.readInt();
|
||||||
|
if (saveCompressionType === SaveCompressionType.NONE) {
|
||||||
|
const chunkData = new Reader(chunkFileReader.readBuffer(contentLength));
|
||||||
|
const chunk = new Chunk(world, x, z, chunkData.readUint8Array(totalByteSize), chunkData.readUint8Array(totalByteSize / 2));
|
||||||
|
resolve(chunk);
|
||||||
|
} else if (saveCompressionType === SaveCompressionType.DEFLATE) {
|
||||||
|
inflate(chunkFileReader.readBuffer(contentLength), (err, data) => {
|
||||||
|
if (err) {
|
||||||
|
return reject(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
const chunkData = new Reader(data);
|
||||||
|
const chunk = new Chunk(world, x, z, chunkData.readUint8Array(totalByteSize), chunkData.readUint8Array(totalByteSize / 2), chunkData.readUint8Array(totalByteSize / 2), chunkData.readUint8Array(totalByteSize / 2));
|
||||||
|
resolve(chunk);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -17,6 +17,11 @@ export class Block {
|
||||||
Block.lightPassage[this.blockId] = value;
|
Block.lightPassage[this.blockId] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public setLightPassage(value:number) {
|
||||||
|
this.lightPassage = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
// Define statics here
|
// Define statics here
|
||||||
static readonly stone = new Block(1);
|
static readonly stone = new Block(1);
|
||||||
static readonly grass = new Block(2);
|
static readonly grass = new Block(2);
|
||||||
|
@ -24,7 +29,7 @@ export class Block {
|
||||||
|
|
||||||
static readonly bedrock = new Block(7);
|
static readonly bedrock = new Block(7);
|
||||||
|
|
||||||
static readonly waterStill = new Block(9);
|
static readonly waterStill = new Block(9).setLightPassage(3);
|
||||||
|
|
||||||
static readonly lavaStill = new Block(11);
|
static readonly lavaStill = new Block(11);
|
||||||
|
|
||||||
|
@ -32,7 +37,9 @@ export class Block {
|
||||||
static readonly gravel = new Block(13);
|
static readonly gravel = new Block(13);
|
||||||
|
|
||||||
static readonly wood = new Block(17);
|
static readonly wood = new Block(17);
|
||||||
static readonly leaves = new Block(18);
|
static readonly leaves = new Block(18).setLightPassage(1);
|
||||||
|
|
||||||
|
static readonly glass = new Block(20).setLightPassage(255);
|
||||||
|
|
||||||
static readonly tallGrass = new Block(31);
|
static readonly tallGrass = new Block(31);
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ export class Player extends EntityLiving {
|
||||||
|
|
||||||
// Mark any unaccounted chunks for unload
|
// Mark any unaccounted chunks for unload
|
||||||
for (const coordPair of this.loadedChunks) {
|
for (const coordPair of this.loadedChunks) {
|
||||||
if (!currentLoads.includes(coordPair)) {
|
if (!currentLoads.includes(coordPair) && this.world.chunkExists(coordPair)) {
|
||||||
this.justUnloaded.push(coordPair);
|
this.justUnloaded.push(coordPair);
|
||||||
const chunkToUnload = this.world.getChunkByCoordPair(coordPair);
|
const chunkToUnload = this.world.getChunkByCoordPair(coordPair);
|
||||||
this.mpClient?.send(new PacketPreChunk(chunkToUnload.x, chunkToUnload.z, false).writeData());
|
this.mpClient?.send(new PacketPreChunk(chunkToUnload.x, chunkToUnload.z, false).writeData());
|
||||||
|
|
|
@ -23,6 +23,7 @@ export class HillyGenerator implements IGenerator {
|
||||||
private caveGenerator2:Noise3D;
|
private caveGenerator2:Noise3D;
|
||||||
private caveGenerator3:Noise3D;
|
private caveGenerator3:Noise3D;
|
||||||
private caveGenerator4:Noise3D;
|
private caveGenerator4:Noise3D;
|
||||||
|
private caveGenerator5:Noise3D;
|
||||||
|
|
||||||
private underwaterGravelGenerator:Noise2D;
|
private underwaterGravelGenerator:Noise2D;
|
||||||
private underwaterSandGenerator:Noise2D;
|
private underwaterSandGenerator:Noise2D;
|
||||||
|
@ -47,6 +48,7 @@ export class HillyGenerator implements IGenerator {
|
||||||
this.caveGenerator2 = this.createGenerator3D();
|
this.caveGenerator2 = this.createGenerator3D();
|
||||||
this.caveGenerator3 = this.createGenerator3D();
|
this.caveGenerator3 = this.createGenerator3D();
|
||||||
this.caveGenerator4 = this.createGenerator3D();
|
this.caveGenerator4 = this.createGenerator3D();
|
||||||
|
this.caveGenerator5 = this.createGenerator3D();
|
||||||
|
|
||||||
this.underwaterGravelGenerator = this.createGenerator2D();
|
this.underwaterGravelGenerator = this.createGenerator2D();
|
||||||
this.underwaterSandGenerator = this.createGenerator2D();
|
this.underwaterSandGenerator = this.createGenerator2D();
|
||||||
|
@ -141,8 +143,9 @@ export class HillyGenerator implements IGenerator {
|
||||||
if (
|
if (
|
||||||
((this.caveGenerator1((chunk.x * 16 + x) / 16, caveY / 16, (chunk.z * 16 + z) / 16) +
|
((this.caveGenerator1((chunk.x * 16 + x) / 16, caveY / 16, (chunk.z * 16 + z) / 16) +
|
||||||
this.caveGenerator2((chunk.x * 16 + x) / 8, caveY / 8, (chunk.z * 16 + z) / 8)) / 2) > 0.45
|
this.caveGenerator2((chunk.x * 16 + x) / 8, caveY / 8, (chunk.z * 16 + z) / 8)) / 2) > 0.45
|
||||||
//this.caveGenerator3((chunk.x * 16 + x) / 256, caveY / 256, (chunk.z * 16 + z) / 256) > 0.6 ||
|
|| this.caveGenerator3((chunk.x * 16 + x) / 16, caveY / 16, (chunk.z * 16 + z) / 16) > 0.6 ||
|
||||||
//this.caveGenerator4((chunk.x * 16 + x) / 128, caveY / 128, (chunk.z * 16 + z) / 128) > 0.6
|
this.caveGenerator4((chunk.x * 16 + x) / 16, caveY / 16, (chunk.z * 16 + z) / 16) > 0.6 ||
|
||||||
|
this.caveGenerator5((chunk.x * 16 + x) / 16, caveY / 16, (chunk.z * 16 + z) / 16) > 0.5
|
||||||
) {
|
) {
|
||||||
if (caveY <= 3) {
|
if (caveY <= 3) {
|
||||||
chunk.setBlock(Block.lavaStill.blockId, x, caveY, z);
|
chunk.setBlock(Block.lavaStill.blockId, x, caveY, z);
|
||||||
|
|
|
@ -33,29 +33,15 @@ export class PacketMapChunk implements IPacket {
|
||||||
|
|
||||||
public writeData() {
|
public writeData() {
|
||||||
return new Promise<Buffer>((resolve, reject) => {
|
return new Promise<Buffer>((resolve, reject) => {
|
||||||
const blocks = new Writer(32768);
|
// TODO: Use block and sky nibble array buffers
|
||||||
const lighting = new Writer(32768);
|
const fakeLighting = new Writer(16384);
|
||||||
|
for (let i = 0; i < 16384; i++) {
|
||||||
let blockMeta = false;
|
fakeLighting.writeUByte(0xFF);
|
||||||
for (let x = 0; x < 16; x++) {
|
|
||||||
for (let z = 0; z < 16; z++) {
|
|
||||||
for (let y = 0; y < 128; y++) {
|
|
||||||
blocks.writeUByte(this.chunk.getBlockId(x, y, z));
|
|
||||||
if (blockMeta) {
|
|
||||||
// Light level 15 for 2 blocks (1111 1111)
|
|
||||||
lighting.writeUByte(0xff); // TODO: Lighting (Client seems to do it's own (when a block update happens) so it's not top priority)
|
|
||||||
lighting.writeUByte(0xff);
|
|
||||||
}
|
|
||||||
// Hack for nibble stuff
|
|
||||||
blockMeta = !blockMeta;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write meta and lighting data into block buffer for compression
|
const data = new Writer().writeBuffer(this.chunk.getBlockBuffer()).writeBuffer(this.chunk.getMetadataBuffer()).writeBuffer(fakeLighting.toBuffer()).writeBuffer(fakeLighting.toBuffer());//.writeBuffer(this.chunk.blockLight.toBuffer()).writeBuffer(this.chunk.skyLight.toBuffer());
|
||||||
blocks.writeBuffer(this.chunk.getMetadataBuffer()).writeBuffer(lighting.toBuffer());
|
|
||||||
|
|
||||||
deflate(blocks.toBuffer(), (err, data) => {
|
deflate(data.toBuffer(), (err, data) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return reject(err);
|
return reject(err);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue