implement torch on wall
This commit is contained in:
@@ -224,7 +224,13 @@ window.Minecraft = class {
|
||||
if (!placedBoundingBox.intersects(this.player.boundingBox)) {
|
||||
let typeId = this.inventory.getItemInSelectedSlot();
|
||||
if (typeId !== 0) {
|
||||
|
||||
// Place block
|
||||
this.world.setBlockAt(x, y, z, typeId);
|
||||
|
||||
// Handle block abilities
|
||||
let block = Block.getById(typeId);
|
||||
block.onBlockPlaced(this.world, x, y, z, hitResult.face);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,18 +158,44 @@ window.BlockRenderer = class {
|
||||
}
|
||||
|
||||
renderTorch(world, block, x, y, z) {
|
||||
let boundingBox = block.getBoundingBox(world, x, y, z);
|
||||
|
||||
// Thickness of the torch
|
||||
let size = 1 / 16;
|
||||
|
||||
let distortX = 0;
|
||||
let distortZ = 0;
|
||||
|
||||
// Attach torch at wall
|
||||
switch (world.getBlockDataAt(x, y, z)) {
|
||||
case 1:
|
||||
distortX = -0.2;
|
||||
break;
|
||||
case 2:
|
||||
distortX = 0.2;
|
||||
break;
|
||||
case 3:
|
||||
distortZ = -0.2;
|
||||
break;
|
||||
case 4:
|
||||
distortZ = 0.2;
|
||||
break;
|
||||
}
|
||||
|
||||
// Model type
|
||||
let centerX = 0.5 + distortX * 1.5;
|
||||
let centerZ = 0.5 + distortZ * 1.5;
|
||||
|
||||
// Lift the torch up
|
||||
if (distortX !== 0 || distortZ !== 0) {
|
||||
y += 0.2;
|
||||
}
|
||||
|
||||
// Vertex mappings
|
||||
let minX = x + 0.5 - size;
|
||||
let minX = x + centerX - size;
|
||||
let minY = y;
|
||||
let minZ = z + 0.5 - size;
|
||||
let maxX = x + 0.5 + size;
|
||||
let minZ = z + centerZ - size;
|
||||
let maxX = x + centerX + size;
|
||||
let maxY = y + 10 / 16;
|
||||
let maxZ = z + 0.5 + size;
|
||||
let maxZ = z + centerZ + size;
|
||||
|
||||
// UV Mapping
|
||||
let textureIndex = block.getTextureForFace(EnumBlockFace.NORTH);
|
||||
@@ -191,36 +217,39 @@ window.BlockRenderer = class {
|
||||
// Set color with shading
|
||||
this.tessellator.setColor(1, 1, 1);
|
||||
|
||||
// Add faceS to tessellator
|
||||
this.addFace(world, EnumBlockFace.NORTH, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV);
|
||||
this.addFace(world, EnumBlockFace.EAST, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV);
|
||||
this.addFace(world, EnumBlockFace.SOUTH, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV);
|
||||
this.addFace(world, EnumBlockFace.WEST, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV);
|
||||
// Add faces to tessellator
|
||||
this.addDistortFace(world, EnumBlockFace.NORTH, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV, distortX, distortZ);
|
||||
this.addDistortFace(world, EnumBlockFace.EAST, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV, distortX, distortZ);
|
||||
this.addDistortFace(world, EnumBlockFace.SOUTH, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV, distortX, distortZ);
|
||||
this.addDistortFace(world, EnumBlockFace.WEST, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV, distortX, distortZ);
|
||||
this.addFace(world, EnumBlockFace.TOP, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV + 8 / 256);
|
||||
}
|
||||
|
||||
renderGuiItem(block) {
|
||||
// Vertex mappings
|
||||
let minX = 0;
|
||||
let minY = 0;
|
||||
let minZ = 0;
|
||||
let maxX = 1;
|
||||
let maxY = 1;
|
||||
let maxZ = 1;
|
||||
|
||||
// UV Mapping
|
||||
let textureIndex = block.getTextureForFace(EnumBlockFace.NORTH);
|
||||
let minU = (textureIndex % 16) / 16.0;
|
||||
let maxU = minU + (16 / 256);
|
||||
let minV = Math.floor(textureIndex / 16) / 16.0;
|
||||
let maxV = minV + (16 / 256);
|
||||
|
||||
// Flip V
|
||||
minV = 1 - minV;
|
||||
maxV = 1 - maxV;
|
||||
|
||||
// Render item
|
||||
this.addFace(null, EnumBlockFace.NORTH, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV);
|
||||
addDistortFace(world, face, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV, distortX, distortZ) {
|
||||
if (face === EnumBlockFace.NORTH) {
|
||||
this.addBlockCorner(world, face, minX, maxY, minZ, minU, minV);
|
||||
this.addBlockCorner(world, face, minX + distortX, minY, minZ + distortZ, minU, maxV);
|
||||
this.addBlockCorner(world, face, maxX + distortX, minY, minZ + distortZ, maxU, maxV);
|
||||
this.addBlockCorner(world, face, maxX, maxY, minZ, maxU, minV);
|
||||
}
|
||||
if (face === EnumBlockFace.SOUTH) {
|
||||
this.addBlockCorner(world, face, minX, maxY, maxZ, maxU, minV);
|
||||
this.addBlockCorner(world, face, maxX, maxY, maxZ, minU, minV);
|
||||
this.addBlockCorner(world, face, maxX + distortX, minY, maxZ + distortZ, minU, maxV);
|
||||
this.addBlockCorner(world, face, minX + distortX, minY, maxZ + distortZ, maxU, maxV);
|
||||
}
|
||||
if (face === EnumBlockFace.WEST) {
|
||||
this.addBlockCorner(world, face, minX + distortX, minY, maxZ + distortZ, minU, maxV);
|
||||
this.addBlockCorner(world, face, minX + distortX, minY, minZ + distortZ, maxU, maxV);
|
||||
this.addBlockCorner(world, face, minX, maxY, minZ, maxU, minV);
|
||||
this.addBlockCorner(world, face, minX, maxY, maxZ, minU, minV);
|
||||
}
|
||||
if (face === EnumBlockFace.EAST) {
|
||||
this.addBlockCorner(world, face, maxX, maxY, maxZ, maxU, minV);
|
||||
this.addBlockCorner(world, face, maxX, maxY, minZ, minU, minV);
|
||||
this.addBlockCorner(world, face, maxX + distortX, minY, minZ + distortZ, minU, maxV);
|
||||
this.addBlockCorner(world, face, maxX + distortX, minY, maxZ + distortZ, maxU, maxV);
|
||||
}
|
||||
}
|
||||
|
||||
renderGuiBlock(group, block, x, y, size) {
|
||||
@@ -266,4 +295,28 @@ window.BlockRenderer = class {
|
||||
mesh.scale.y = size;
|
||||
mesh.scale.z = size;
|
||||
}
|
||||
|
||||
renderGuiItem(block) {
|
||||
// Vertex mappings
|
||||
let minX = 0;
|
||||
let minY = 0;
|
||||
let minZ = 0;
|
||||
let maxX = 1;
|
||||
let maxY = 1;
|
||||
let maxZ = 1;
|
||||
|
||||
// UV Mapping
|
||||
let textureIndex = block.getTextureForFace(EnumBlockFace.NORTH);
|
||||
let minU = (textureIndex % 16) / 16.0;
|
||||
let maxU = minU + (16 / 256);
|
||||
let minV = Math.floor(textureIndex / 16) / 16.0;
|
||||
let maxV = minV + (16 / 256);
|
||||
|
||||
// Flip V
|
||||
minV = 1 - minV;
|
||||
maxV = 1 - maxV;
|
||||
|
||||
// Render item
|
||||
this.addFace(null, EnumBlockFace.NORTH, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV);
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,9 @@ window.ScreenRenderer = class {
|
||||
this.stack2d.clearRect(0, 0, this.window.width, this.window.height);
|
||||
|
||||
// Render in-game overlay
|
||||
this.minecraft.ingameOverlay.render(this.stack2d, mouseX, mouseY, partialTicks);
|
||||
if (this.minecraft.loadingScreen === null) {
|
||||
this.minecraft.ingameOverlay.render(this.stack2d, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
// Render current screen
|
||||
if (!(this.minecraft.currentScreen === null)) {
|
||||
|
||||
@@ -29,7 +29,7 @@ window.Chunk = class {
|
||||
// Calculate height map
|
||||
for (let x = 0; x < 16; x++) {
|
||||
for (let z = 0; z < 16; z++) {
|
||||
this.setHeightAt(x, z, 0); // TODO set to 0 to calculate proper lightning
|
||||
this.setHeightAt(x, z, 0);
|
||||
this.updateHeightMap(x, World.TOTAL_HEIGHT, z);
|
||||
}
|
||||
}
|
||||
@@ -238,19 +238,32 @@ window.Chunk = class {
|
||||
section.setLightAt(sourceType, x, y & 15, z, level);
|
||||
}
|
||||
|
||||
setBlockAt(x, y, z, typeId) {
|
||||
setBlockDataAt(x, y, z, data) {
|
||||
this.setBlockAt(x, y, z, this.getBlockAt(x, y, z), data);
|
||||
}
|
||||
|
||||
setBlockAt(x, y, z, typeId, data = 0) {
|
||||
let section = this.getSection(y >> 4);
|
||||
let yInSection = y & 15;
|
||||
|
||||
let height = this.getHeightAt(x, z);
|
||||
let prevTypeId = this.getBlockAt(x, y, z);
|
||||
if (prevTypeId === typeId) {
|
||||
let prevTypeId = section.getBlockAt(x, yInSection, z);
|
||||
let prevData = section.getBlockDataAt(x, yInSection, z);
|
||||
|
||||
// Check if block type has changed
|
||||
if (prevTypeId === typeId && prevData === data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.getSection(y >> 4).setBlockAt(x, y & 15, z, typeId);
|
||||
// Update block type and data
|
||||
section.setBlockAt(x, yInSection, z, typeId);
|
||||
section.setBlockDataAt(x, yInSection, z, data);
|
||||
|
||||
if (!this.loaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update height map
|
||||
let block = Block.getById(typeId);
|
||||
if (typeId !== 0 && block.isSolid()) {
|
||||
if (y >= height) {
|
||||
@@ -263,11 +276,18 @@ window.Chunk = class {
|
||||
let totalX = this.x * 16 + x;
|
||||
let totalZ = this.z * 16 + z;
|
||||
|
||||
// Update light
|
||||
this.world.updateLight(EnumSkyBlock.SKY, totalX, y, totalZ, totalX, y, totalZ);
|
||||
this.world.updateLight(EnumSkyBlock.BLOCK, totalX, y, totalZ, totalX, y, totalZ);
|
||||
|
||||
// Notify surrounding blocks
|
||||
this.notifyNeighbors(x, z);
|
||||
this.setModifiedAllSections();
|
||||
|
||||
// Handle block abilities
|
||||
if (typeId !== 0) {
|
||||
block.onBlockAdded(this.world, totalX, y, totalZ);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -279,6 +299,10 @@ window.Chunk = class {
|
||||
return this.getSection(y >> 4).getBlockAt(x, y & 15, z);
|
||||
}
|
||||
|
||||
getBlockDataAt(x, y, z) {
|
||||
return this.getSection(y >> 4).getBlockDataAt(x, y & 15, z);
|
||||
}
|
||||
|
||||
getSection(y) {
|
||||
return this.sections[y];
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ window.ChunkSection = class {
|
||||
this.isModified = false;
|
||||
|
||||
this.blocks = [];
|
||||
this.blocksData = [];
|
||||
this.blockLight = [];
|
||||
this.skyLight = [];
|
||||
|
||||
@@ -32,6 +33,7 @@ window.ChunkSection = class {
|
||||
for (let tZ = 0; tZ < ChunkSection.SIZE; tZ++) {
|
||||
let index = tY << 8 | tZ << 4 | tX;
|
||||
this.blocks[index] = 0;
|
||||
this.blocksData[index] = 0;
|
||||
this.blockLight[index] = 0;
|
||||
this.skyLight[index] = 0;
|
||||
}
|
||||
@@ -77,6 +79,11 @@ window.ChunkSection = class {
|
||||
return this.blocks[index];
|
||||
}
|
||||
|
||||
getBlockDataAt(x, y, z) {
|
||||
let index = y << 8 | z << 4 | x;
|
||||
return this.blocksData[index];
|
||||
}
|
||||
|
||||
setBlockAt(x, y, z, typeId) {
|
||||
let index = y << 8 | z << 4 | x;
|
||||
this.blocks[index] = typeId;
|
||||
@@ -84,6 +91,13 @@ window.ChunkSection = class {
|
||||
this.isModified = true;
|
||||
}
|
||||
|
||||
setBlockDataAt(x, y, z, data) {
|
||||
let index = y << 8 | z << 4 | x;
|
||||
this.blocksData[index] = data;
|
||||
|
||||
this.isModified = true;
|
||||
}
|
||||
|
||||
setLightAt(sourceType, x, y, z, lightLevel) {
|
||||
let index = y << 8 | z << 4 | x;
|
||||
|
||||
|
||||
@@ -278,11 +278,20 @@ window.World = class {
|
||||
this.onBlockChanged(x, y, z);
|
||||
}
|
||||
|
||||
setBlockDataAt(x, y, z, data) {
|
||||
this.getChunkAt(x >> 4, z >> 4).setBlockDataAt(x & 15, y, z & 15, data);
|
||||
}
|
||||
|
||||
getBlockAt(x, y, z) {
|
||||
let chunkSection = this.getChunkAtBlock(x, y, z);
|
||||
return chunkSection == null ? 0 : chunkSection.getBlockAt(x & 15, y & 15, z & 15);
|
||||
}
|
||||
|
||||
getBlockDataAt(x, y, z) {
|
||||
let chunkSection = this.getChunkAtBlock(x, y, z);
|
||||
return chunkSection == null ? 0 : chunkSection.getBlockDataAt(x & 15, y & 15, z & 15);
|
||||
}
|
||||
|
||||
getBlockAtFace(x, y, z, face) {
|
||||
return this.getBlockAt(x + face.x, y + face.y, z + face.z);
|
||||
}
|
||||
|
||||
@@ -64,6 +64,14 @@ window.Block = class {
|
||||
return this.boundingBox;
|
||||
}
|
||||
|
||||
onBlockAdded(world, x, y, z) {
|
||||
|
||||
}
|
||||
|
||||
onBlockPlaced(world, x, y, z, face) {
|
||||
|
||||
}
|
||||
|
||||
collisionRayTrace(x, y, z, start, end) {
|
||||
start = start.addVector(-x, -y, -z);
|
||||
end = end.addVector(-x, -y, -z);
|
||||
|
||||
@@ -4,6 +4,14 @@ window.BlockTorch = class extends Block {
|
||||
super(id, textureSlotId);
|
||||
|
||||
this.boundingBox = new BoundingBox(0.4, 0.0, 0.4, 0.6, 0.6, 0.6);
|
||||
|
||||
this.dataFaces = [
|
||||
EnumBlockFace.WEST,
|
||||
EnumBlockFace.EAST,
|
||||
EnumBlockFace.NORTH,
|
||||
EnumBlockFace.SOUTH,
|
||||
EnumBlockFace.BOTTOM,
|
||||
]
|
||||
}
|
||||
|
||||
getLightValue() {
|
||||
@@ -17,4 +25,30 @@ window.BlockTorch = class extends Block {
|
||||
getRenderType() {
|
||||
return BlockRenderType.TORCH;
|
||||
}
|
||||
|
||||
onBlockAdded(world, x, y, z) {
|
||||
for (let i = this.dataFaces.length - 1; i >= 0; i--) {
|
||||
let dataFace = this.dataFaces[i];
|
||||
|
||||
if (world.isSolidBlockAt(x + dataFace.x, y + dataFace.y, z + dataFace.z)) {
|
||||
world.setBlockDataAt(x, y, z, i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onBlockPlaced(world, x, y, z, face) {
|
||||
let meta = world.getBlockDataAt(x, y, z);
|
||||
|
||||
for (let i in this.dataFaces) {
|
||||
let dataFace = this.dataFaces[i];
|
||||
|
||||
if (face === dataFace.opposite() && world.isSolidBlockAt(x + dataFace.x, y + dataFace.y, z + dataFace.z)) {
|
||||
meta = parseInt(i) + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
world.getChunkSectionAt(x >> 4, y >> 4, z >> 4).setBlockDataAt(x & 15, y & 15, z & 15, meta);
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,31 @@ window.EnumBlockFace = class {
|
||||
return this.z !== 0;
|
||||
}
|
||||
|
||||
opposite() {
|
||||
if (this === EnumBlockFace.TOP) {
|
||||
return EnumBlockFace.BOTTOM;
|
||||
}
|
||||
if (this === EnumBlockFace.BOTTOM) {
|
||||
return EnumBlockFace.TOP;
|
||||
}
|
||||
|
||||
if (this === EnumBlockFace.NORTH) {
|
||||
return EnumBlockFace.SOUTH;
|
||||
}
|
||||
if (this === EnumBlockFace.SOUTH) {
|
||||
return EnumBlockFace.NORTH;
|
||||
}
|
||||
|
||||
if (this === EnumBlockFace.EAST) {
|
||||
return EnumBlockFace.WEST;
|
||||
}
|
||||
if (this === EnumBlockFace.WEST) {
|
||||
return EnumBlockFace.EAST;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static values() {
|
||||
return [
|
||||
EnumBlockFace.TOP,
|
||||
|
||||
Reference in New Issue
Block a user