implement torch on wall

This commit is contained in:
LabyStudio
2022-02-13 04:17:03 +01:00
parent 9078d34ab0
commit bcdbe4240b
9 changed files with 215 additions and 40 deletions
+6
View File
@@ -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)) {
+30 -6
View File
@@ -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,