improve mojang lightning
This commit is contained in:
@@ -12,7 +12,7 @@ window.GameWindow = class {
|
|||||||
|
|
||||||
// Stats
|
// Stats
|
||||||
this.stats = new Stats()
|
this.stats = new Stats()
|
||||||
this.stats.showPanel(1);
|
this.stats.showPanel(0);
|
||||||
wrapper.appendChild(this.stats.dom);
|
wrapper.appendChild(this.stats.dom);
|
||||||
|
|
||||||
// Add web renderer canvas to wrapper
|
// Add web renderer canvas to wrapper
|
||||||
|
|||||||
@@ -27,6 +27,10 @@ window.Minecraft = class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
|
// Load spawn chunk
|
||||||
|
this.world.getChunkAt(0, 0);
|
||||||
|
this.player.respawn();
|
||||||
|
|
||||||
// Start render loop
|
// Start render loop
|
||||||
this.running = true;
|
this.running = true;
|
||||||
this.requestNextFrame();
|
this.requestNextFrame();
|
||||||
|
|||||||
@@ -42,22 +42,33 @@ window.Player = class {
|
|||||||
this.prevFovModifier = 0;
|
this.prevFovModifier = 0;
|
||||||
this.fovModifier = 0;
|
this.fovModifier = 0;
|
||||||
this.timeFovChanged = 0;
|
this.timeFovChanged = 0;
|
||||||
|
|
||||||
this.resetPos();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resetPos() {
|
respawn() {
|
||||||
this.setPos(0, 80, 0);
|
let spawnY = this.world.getHeightAt(0, 0);
|
||||||
|
this.setPosition(0, spawnY + 8, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
setPos(x, y, z) {
|
setPosition(x, y, z) {
|
||||||
this.x = x;
|
let width = 0.3;
|
||||||
this.y = y;
|
let height = 0.9;
|
||||||
this.z = z;
|
this.boundingBox = new BoundingBox(
|
||||||
|
x - width,
|
||||||
|
y - height,
|
||||||
|
z - width,
|
||||||
|
x + width,
|
||||||
|
y + height,
|
||||||
|
z + width
|
||||||
|
);
|
||||||
|
|
||||||
let w = 0.3;
|
this.motionX = 0;
|
||||||
let h = 0.9;
|
this.motionY = 0;
|
||||||
this.boundingBox = new BoundingBox(x - w, y - h, z - w, x + w, y + h, z + w);
|
this.motionZ = 0;
|
||||||
|
|
||||||
|
// Update position
|
||||||
|
this.x = (this.boundingBox.minX + this.boundingBox.maxX) / 2.0;
|
||||||
|
this.y = this.boundingBox.minY;
|
||||||
|
this.z = (this.boundingBox.minZ + this.boundingBox.maxZ) / 2.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
turn(motionX, motionY) {
|
turn(motionX, motionY) {
|
||||||
@@ -299,7 +310,7 @@ window.Player = class {
|
|||||||
let sneaking = false;
|
let sneaking = false;
|
||||||
|
|
||||||
if (Keyboard.isKeyDown("KeyR")) { // R
|
if (Keyboard.isKeyDown("KeyR")) { // R
|
||||||
this.resetPos();
|
this.respawn();
|
||||||
}
|
}
|
||||||
if (Keyboard.isKeyDown("KeyW")) { // W
|
if (Keyboard.isKeyDown("KeyW")) { // W
|
||||||
moveForward++;
|
moveForward++;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
window.BlockRenderer = class {
|
window.BlockRenderer = class {
|
||||||
|
|
||||||
static CLASSIC_LIGHTNING = true;
|
static CLASSIC_LIGHTNING = false;
|
||||||
|
|
||||||
constructor(worldRenderer) {
|
constructor(worldRenderer) {
|
||||||
this.worldRenderer = worldRenderer;
|
this.worldRenderer = worldRenderer;
|
||||||
|
|||||||
@@ -26,27 +26,22 @@ window.Chunk = class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
generateSkylightMap() {
|
generateSkylightMap() {
|
||||||
let highest = World.TOTAL_HEIGHT;
|
// Calculate height map
|
||||||
for (let x = 0; x < 16; x++) {
|
for (let x = 0; x < 16; x++) {
|
||||||
for (let z = 0; z < 16; z++) {
|
for (let z = 0; z < 16; z++) {
|
||||||
this.heightMap[z << 4 | x] = -1;
|
this.setHeightAt(x, z, 0); // TODO set to 0 to calculate proper lightning
|
||||||
|
|
||||||
this.updateHeightMap(x, World.TOTAL_HEIGHT, z);
|
this.updateHeightMap(x, World.TOTAL_HEIGHT, z);
|
||||||
|
|
||||||
if ((this.heightMap[z << 4 | x] & 0xff) < highest) {
|
|
||||||
highest = this.heightMap[z << 4 | x] & 0xff;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.highestY = highest;
|
// Update light of neighbor blocks
|
||||||
for (let k = 0; k < 16; k++) {
|
for (let x = 0; x < 16; x++) {
|
||||||
for (let i1 = 0; i1 < 16; i1++) {
|
for (let z = 0; z < 16; z++) {
|
||||||
this.notifyNeighbors(k, i1);
|
this.notifyNeighbors(x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rebuild all sections
|
||||||
this.setModifiedAllSections();
|
this.setModifiedAllSections();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,57 +71,34 @@ window.Chunk = class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateHeightMap(relX, y, relZ) {
|
updateHeightMap(relX, y, relZ) {
|
||||||
let currentHighestY = this.heightMap[relZ << 4 | relX] & 0xff;
|
let currentHighestY = this.getHeightAt(relX, relZ);
|
||||||
let highestY = currentHighestY;
|
let highestY = currentHighestY;
|
||||||
if (y > currentHighestY) {
|
if (y > currentHighestY) {
|
||||||
highestY = y;
|
highestY = y;
|
||||||
}
|
}
|
||||||
while (highestY > 0) {
|
|
||||||
let typeId = this.getBlockAt(relX, highestY, relZ);
|
|
||||||
let block = Block.getById(typeId);
|
|
||||||
|
|
||||||
if (typeId !== 0 && block.getOpacity() !== 0) {
|
highestY = this.calculateHeightAt(relX, relZ, highestY);
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
highestY--;
|
|
||||||
}
|
|
||||||
if (highestY === currentHighestY) {
|
if (highestY === currentHighestY) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//this.world.heightLevelChanged(relX, relZ, highestY, currentHighestY);
|
|
||||||
this.heightMap[relZ << 4 | relX] = highestY;
|
|
||||||
if (highestY < this.highestY) {
|
|
||||||
this.highestY = highestY;
|
|
||||||
} else {
|
|
||||||
let highest = 127;
|
|
||||||
for (let cx = 0; cx < 16; cx++) {
|
|
||||||
for (let cz = 0; cz < 16; cz++) {
|
|
||||||
if ((this.heightMap[cz << 4 | cx] & 0xff) < highest) {
|
|
||||||
highest = this.heightMap[cz << 4 | cx] & 0xff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
this.setHeightAt(relX, relZ, highestY);
|
||||||
|
|
||||||
this.highestY = highest;
|
|
||||||
}
|
|
||||||
|
|
||||||
let x = this.x * 16 + relX;
|
let x = this.x * 16 + relX;
|
||||||
let z = this.z * 16 + relZ;
|
let z = this.z * 16 + relZ;
|
||||||
|
|
||||||
if (highestY < currentHighestY) {
|
if (highestY < currentHighestY) {
|
||||||
for (let l2 = highestY; l2 < currentHighestY; l2++) {
|
for (let hy = highestY; hy < currentHighestY; hy++) {
|
||||||
this.setLightAt(EnumSkyBlock.SKY, relX, l2, relZ, 15);
|
this.setLightAt(EnumSkyBlock.SKY, relX, hy, relZ, 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
this.world.updateLight(EnumSkyBlock.SKY, x, currentHighestY, z, x, highestY, z);
|
this.world.updateLight(EnumSkyBlock.SKY, x, currentHighestY, z, x, highestY, z);
|
||||||
for (let hy = currentHighestY; hy < highestY; hy++) {
|
for (let hy = currentHighestY; hy < highestY; hy++) {
|
||||||
this.setLightAt(EnumSkyBlock.SKY, relX, hy, relZ, 0);
|
this.setLightAt(EnumSkyBlock.SKY, relX, hy, relZ, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let lightLevel = 15;
|
let lightLevel = 15;
|
||||||
let prevHeight = highestY;
|
let prevHeight = highestY;
|
||||||
while (highestY > 0 && lightLevel > 0) {
|
while (highestY > 0 && lightLevel > 0) {
|
||||||
@@ -147,15 +119,7 @@ window.Chunk = class {
|
|||||||
this.setLightAt(EnumSkyBlock.SKY, relX, highestY, relZ, lightLevel);
|
this.setLightAt(EnumSkyBlock.SKY, relX, highestY, relZ, lightLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (highestY > 0) {
|
highestY = this.calculateHeightAt(relX, relZ, highestY);
|
||||||
let typeId = this.getBlockID(relX, highestY - 1, relZ);
|
|
||||||
let block = Block.getById(typeId);
|
|
||||||
|
|
||||||
if (typeId !== 0 && block.isSolid()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
highestY--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (highestY !== prevHeight) {
|
if (highestY !== prevHeight) {
|
||||||
this.world.updateLight(EnumSkyBlock.SKY, x - 1, highestY, z - 1, x + 1, prevHeight, z + 1);
|
this.world.updateLight(EnumSkyBlock.SKY, x - 1, highestY, z - 1, x + 1, prevHeight, z + 1);
|
||||||
@@ -163,34 +127,76 @@ window.Chunk = class {
|
|||||||
this.setModifiedAllSections();
|
this.setModifiedAllSections();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
calculateHeightAt(x, z, startY) {
|
||||||
|
let y = startY;
|
||||||
|
while (y > 0) {
|
||||||
|
let typeId = this.getBlockAt(x, y - 1, z);
|
||||||
|
let block = Block.getById(typeId);
|
||||||
|
let opacity = typeId === 0 ? 0 : block.getOpacity();
|
||||||
|
|
||||||
|
if (opacity !== 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
y--;
|
||||||
|
}
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateHeightMapAt(x, z) {
|
||||||
|
let y = this.calculateHeightAt(x, z, World.TOTAL_HEIGHT);
|
||||||
|
this.setHeightAt(x, z, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
setHeightAt(x, z, height) {
|
||||||
|
this.heightMap[z << 4 | x] = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the highest solid block or above
|
||||||
|
*/
|
||||||
|
isHighestBlock(x, y, z) {
|
||||||
|
return y >= this.getHighestBlockAt(x, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is above the highest solid block
|
||||||
|
*/
|
||||||
|
isAboveGround(x, y, z) {
|
||||||
|
return y >= this.getHeightAt(x, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the first non-solid block
|
||||||
|
*/
|
||||||
|
getHeightAt(x, z) {
|
||||||
|
return this.heightMap[z << 4 | x];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the highest solid block
|
||||||
|
*/
|
||||||
|
getHighestBlockAt(x, z) {
|
||||||
|
return this.getHeightAt(x, z) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
setLightAt(sourceType, x, y, z, level) {
|
setLightAt(sourceType, x, y, z, level) {
|
||||||
this.getSection(y >> 4).setLightAt(sourceType, x, y & 15, z, level);
|
let section = this.getSection(y >> 4);
|
||||||
|
section.setLightAt(sourceType, x, y & 15, z, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
setBlockAt(x, y, z, typeId) {
|
setBlockAt(x, y, z, typeId) {
|
||||||
let byte0 = typeId;
|
let height = this.getHeightAt(x, z);
|
||||||
let height = this.heightMap[z << 4 | x] & 0xff;
|
|
||||||
|
|
||||||
let prevTypeId = this.getBlockAt(x, y, z);
|
let prevTypeId = this.getBlockAt(x, y, z);
|
||||||
if (prevTypeId === typeId) {
|
if (prevTypeId === typeId) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let totalX = this.x * 16 + x;
|
this.getSection(y >> 4).setBlockAt(x, y & 15, z, typeId);
|
||||||
let totalZ = this.z * 16 + z;
|
|
||||||
|
|
||||||
this.getSection(y >> 4).setBlockAt(x, y & 15, z, byte0);
|
|
||||||
|
|
||||||
if (!this.loaded) {
|
if (!this.loaded) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (k1 !== 0 && !this.worldObj.multiplayerWorld) {
|
|
||||||
//Block.blocksList[k1].onBlockRemoval(this.world, l1, j, i2);
|
|
||||||
//}
|
|
||||||
//this.data.setNibble(i, j, k, i1);
|
|
||||||
//if (!this.worldObj.worldProvider.field_6478_e) {
|
|
||||||
|
|
||||||
let block = Block.getById(typeId);
|
let block = Block.getById(typeId);
|
||||||
if (typeId !== 0 && block.isSolid()) {
|
if (typeId !== 0 && block.isSolid()) {
|
||||||
if (y >= height) {
|
if (y >= height) {
|
||||||
@@ -200,18 +206,13 @@ window.Chunk = class {
|
|||||||
this.updateHeightMap(x, y, z);
|
this.updateHeightMap(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let totalX = this.x * 16 + x;
|
||||||
|
let totalZ = this.z * 16 + z;
|
||||||
|
|
||||||
this.world.updateLight(EnumSkyBlock.SKY, totalX, y, totalZ, totalX, y, totalZ);
|
this.world.updateLight(EnumSkyBlock.SKY, totalX, y, totalZ, totalX, y, totalZ);
|
||||||
//}
|
|
||||||
|
|
||||||
this.world.updateLight(EnumSkyBlock.BLOCK, totalX, y, totalZ, totalX, y, totalZ);
|
this.world.updateLight(EnumSkyBlock.BLOCK, totalX, y, totalZ, totalX, y, totalZ);
|
||||||
|
|
||||||
this.notifyNeighbors(x, z);
|
this.notifyNeighbors(x, z);
|
||||||
|
|
||||||
if (typeId !== 0) {
|
|
||||||
//Block.blocksList[l].onBlockAdded(this.worldObj, l1, j, i2);
|
|
||||||
}
|
|
||||||
|
|
||||||
//this.data.setNibble(i, j, k, i1);
|
|
||||||
|
|
||||||
this.setModifiedAllSections();
|
this.setModifiedAllSections();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -224,14 +225,6 @@ window.Chunk = class {
|
|||||||
return this.getSection(y >> 4).getBlockAt(x, y & 15, z);
|
return this.getSection(y >> 4).getBlockAt(x, y & 15, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
isHighestBlock(x, y, z) {
|
|
||||||
return y >= (this.heightMap[z << 4 | x] & 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
getHeightAt(x, z) {
|
|
||||||
return this.heightMap[z << 4 | x] & 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
getSection(y) {
|
getSection(y) {
|
||||||
return this.sections[y];
|
return this.sections[y];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
window.World = class {
|
window.World = class {
|
||||||
|
|
||||||
static TOTAL_HEIGHT = ChunkSection.SIZE * 16 - 1;
|
static TOTAL_HEIGHT = ChunkSection.SIZE * 8 - 1; // ChunkSection.SIZE * 16 - 1;
|
||||||
|
|
||||||
constructor(minecraft) {
|
constructor(minecraft) {
|
||||||
this.minecrat = minecraft;
|
this.minecrat = minecraft;
|
||||||
|
|
||||||
this.group = new THREE.Object3D();
|
this.group = new THREE.Object3D();
|
||||||
this.group.matrixAutoUpdate = false;
|
this.group.matrixAutoUpdate = false;
|
||||||
|
|
||||||
this.chunks = new Map();
|
this.chunks = new Map();
|
||||||
|
this.lightUpdateQueue = [];
|
||||||
|
|
||||||
// Load world
|
// Load world
|
||||||
this.generator = new WorldGenerator(this, Date.now() % 100000);
|
this.generator = new WorldGenerator(this, Date.now() % 100000);
|
||||||
|
|
||||||
this.lightUpdateQueue = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onTick() {
|
onTick() {
|
||||||
@@ -81,14 +81,35 @@ window.World = class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateLights() {
|
updateLights() {
|
||||||
// Update lights in queue
|
let scope = this;
|
||||||
let i = 5000;
|
|
||||||
while (this.lightUpdateQueue.length > 0) {
|
if (this.lightUpdateQueue.length > 10) {
|
||||||
if (i <= 0) {
|
// Update lights async
|
||||||
return true;
|
setTimeout(function () {
|
||||||
|
// Update lights in queue
|
||||||
|
let i = 5000;
|
||||||
|
while (scope.lightUpdateQueue.length > 0) {
|
||||||
|
if (i <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let meta = scope.lightUpdateQueue.shift();
|
||||||
|
meta.updateBlockLightning(scope);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
|
} else {
|
||||||
|
// Update lights in queue
|
||||||
|
let i = 10;
|
||||||
|
while (scope.lightUpdateQueue.length > 0) {
|
||||||
|
if (i <= 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let meta = scope.lightUpdateQueue.shift();
|
||||||
|
meta.updateBlockLightning(scope);
|
||||||
|
i--;
|
||||||
}
|
}
|
||||||
this.lightUpdateQueue.shift().updateBlockLightning(this);
|
|
||||||
i--;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -116,8 +137,11 @@ window.World = class {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add light update region to queue
|
||||||
this.lightUpdateQueue.push(new MetadataChunkBlock(sourceType, x1, y1, z1, x2, y2, z2));
|
this.lightUpdateQueue.push(new MetadataChunkBlock(sourceType, x1, y1, z1, x2, y2, z2));
|
||||||
if (this.lightUpdateQueue.length > 0x186a0) {
|
|
||||||
|
// Max light updates in queue
|
||||||
|
if (this.lightUpdateQueue.length > 100000) {
|
||||||
this.lightUpdateQueue = [];
|
this.lightUpdateQueue = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -141,7 +165,7 @@ window.World = class {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (sourceType === EnumSkyBlock.SKY) {
|
if (sourceType === EnumSkyBlock.SKY) {
|
||||||
if (this.isHighestBlock(x, y, z)) {
|
if (this.isAboveGround(x, y, z)) {
|
||||||
level = 15;
|
level = 15;
|
||||||
}
|
}
|
||||||
} else if (sourceType === EnumSkyBlock.BLOCK) {
|
} else if (sourceType === EnumSkyBlock.BLOCK) {
|
||||||
@@ -155,17 +179,40 @@ window.World = class {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the first non-solid block
|
||||||
|
*/
|
||||||
getHeightAt(x, z) {
|
getHeightAt(x, z) {
|
||||||
if (!this.chunkExists(x >> 4, z >> 4)) {
|
if (!this.chunkExists(x >> 4, z >> 4)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.getChunkAt(x >> 4, z >> 4).getHeightAt(x & 15, z & 15);
|
return this.getChunkAt(x >> 4, z >> 4).getHeightAt(x & 15, z & 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the highest solid block
|
||||||
|
*/
|
||||||
|
getHighestBlockAt(x, z) {
|
||||||
|
if (!this.chunkExists(x >> 4, z >> 4)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return this.getChunkAt(x >> 4, z >> 4).getHighestBlockAt(x & 15, z & 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the highest solid block or above
|
||||||
|
*/
|
||||||
isHighestBlock(x, y, z) {
|
isHighestBlock(x, y, z) {
|
||||||
let chunk = this.getChunkAt(x >> 4, z >> 4)
|
let chunk = this.getChunkAt(x >> 4, z >> 4)
|
||||||
return y >= chunk.getHeightAt(x & 15, z & 15);
|
return chunk.isHighestBlock(x & 15, y, z & 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is above the highest solid block
|
||||||
|
*/
|
||||||
|
isAboveGround(x, y, z) {
|
||||||
|
let chunk = this.getChunkAt(x >> 4, z >> 4)
|
||||||
|
return chunk.isAboveGround(x & 15, y, z & 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
getTotalLightAt(x, y, z) {
|
getTotalLightAt(x, y, z) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ window.BlockWater = class extends Block {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getOpacity() {
|
getOpacity() {
|
||||||
return 0.93;
|
return 0.01;
|
||||||
}
|
}
|
||||||
|
|
||||||
isSolid() {
|
isSolid() {
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ window.WorldGenerator = class {
|
|||||||
if (perlin > 0 && this.random.nextInt(2) === 0) {
|
if (perlin > 0 && this.random.nextInt(2) === 0) {
|
||||||
|
|
||||||
// Get the highest block at this position
|
// Get the highest block at this position
|
||||||
let highestY = this.world.getHeightAt(absoluteX, absoluteZ);
|
let highestY = this.world.getHighestBlockAt(absoluteX, absoluteZ);
|
||||||
|
|
||||||
// Don't place a tree if there is no grass
|
// Don't place a tree if there is no grass
|
||||||
if (this.world.getBlockAt(absoluteX, highestY, absoluteZ) === Block.GRASS.getId()
|
if (this.world.getBlockAt(absoluteX, highestY, absoluteZ) === Block.GRASS.getId()
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ window.MetadataChunkBlock = class {
|
|||||||
let level = 0;
|
let level = 0;
|
||||||
|
|
||||||
if (this.type === EnumSkyBlock.SKY) {
|
if (this.type === EnumSkyBlock.SKY) {
|
||||||
if (world.isHighestBlock(x, y, z)) {
|
if (world.isAboveGround(x, y, z)) {
|
||||||
level = 15;
|
level = 15;
|
||||||
}
|
}
|
||||||
} else if (this.type === EnumSkyBlock.BLOCK) {
|
} else if (this.type === EnumSkyBlock.BLOCK) {
|
||||||
|
|||||||
Reference in New Issue
Block a user