import Block from "../client/world/block/Block.js"; import EnumSkyBlock from "./EnumSkyBlock.js"; import World from "../client/world/World.js"; export default class MetadataChunkBlock { constructor(type, x1, y1, z1, x2, y2, z2) { this.type = type; this.x1 = x1; this.y1 = y1; this.z1 = z1; this.x2 = x2; this.y2 = y2; this.z2 = z2; } updateBlockLightning(world) { let centerX = (this.x2 - this.x1) + 1; let centerY = (this.y2 - this.y1) + 1; let centerZ = (this.z2 - this.z1) + 1; let index = centerX * centerY * centerZ; if (index > 32768) { return; } for (let x = this.x1; x <= this.x2; x++) { for (let z = this.z1; z <= this.z2; z++) { if (!world.blockExists(x, 0, z)) { continue; } for (let y = this.y1; y <= this.y2; y++) { if (y < 0 || y >= World.TOTAL_HEIGHT) { continue; } let savedLightValue = world.getSavedLightValue(this.type, x, y, z); let newLevel = 0; let typeId = world.getBlockAt(x, y, z); let block = Block.getById(typeId); let opacity = typeId === 0 ? 0 : Math.round(block.getOpacity() * 255); if (opacity === 0) { opacity = 1; } let level = 0; if (this.type === EnumSkyBlock.SKY) { if (world.isAboveGround(x, y, z)) { level = 15; } } else if (this.type === EnumSkyBlock.BLOCK) { level = typeId === 0 ? 0 : block.getLightValue(); } if (opacity >= 15 && level === 0) { newLevel = 0; } else { let x1Level = world.getSavedLightValue(this.type, x - 1, y, z); let x2Level = world.getSavedLightValue(this.type, x + 1, y, z); let bottomLevel = world.getSavedLightValue(this.type, x, y - 1, z); let topLevel = world.getSavedLightValue(this.type, x, y + 1, z); let z1Level = world.getSavedLightValue(this.type, x, y, z - 1); let z2Level = world.getSavedLightValue(this.type, x, y, z + 1); newLevel = x1Level; if (x2Level > newLevel) { newLevel = x2Level; } if (bottomLevel > newLevel) { newLevel = bottomLevel; } if (topLevel > newLevel) { newLevel = topLevel; } if (z1Level > newLevel) { newLevel = z1Level; } if (z2Level > newLevel) { newLevel = z2Level; } newLevel -= opacity; if (newLevel < 0) { newLevel = 0; } if (level > newLevel) { newLevel = level; } } if (savedLightValue === newLevel) { continue; } world.setLightAt(this.type, x, y, z, newLevel); let decreasedLevel = newLevel - 1; if (decreasedLevel < 0) { decreasedLevel = 0; } world.neighborLightPropagationChanged(this.type, x - 1, y, z, decreasedLevel); world.neighborLightPropagationChanged(this.type, x, y - 1, z, decreasedLevel); world.neighborLightPropagationChanged(this.type, x, y, z - 1, decreasedLevel); if (x + 1 >= this.x2) { world.neighborLightPropagationChanged(this.type, x + 1, y, z, decreasedLevel); } if (y + 1 >= this.y2) { world.neighborLightPropagationChanged(this.type, x, y + 1, z, decreasedLevel); } if (z + 1 >= this.z2) { world.neighborLightPropagationChanged(this.type, x, y, z + 1, decreasedLevel); } } } } } isOutsideOf(x1, y1, z1, x2, y2, z2) { if (x1 >= this.x1 && y1 >= this.y1 && z1 >= this.z1 && x2 <= this.x2 && y2 <= this.y2 && z2 <= this.z2) { return true; } let radius = 1; if (x1 >= this.x1 - radius && y1 >= this.y1 - radius && z1 >= this.z1 - radius && x2 <= this.x2 + radius && y2 <= this.y2 + radius && z2 <= this.z2 + radius) { let distanceX = this.x2 - this.x1; let distanceY = this.y2 - this.y1; let distanceZ = this.z2 - this.z1; if (x1 > this.x1) { x1 = this.x1; } if (y1 > this.y1) { y1 = this.y1; } if (z1 > this.z1) { z1 = this.z1; } if (x2 < this.x2) { x2 = this.x2; } if (y2 < this.y2) { y2 = this.y2; } if (z2 < this.z2) { z2 = this.z2; } let newDistanceX = x2 - x1; let newDistanceY = y2 - y1; let newDistanceZ = z2 - z1; let size = distanceX * distanceY * distanceZ; let newSize = newDistanceX * newDistanceY * newDistanceZ; if (newSize - size <= 2) { this.x1 = x1; this.y1 = y1; this.z1 = z1; this.x2 = x2; this.y2 = y2; this.z2 = z2; return true; } } return false; } }