import { instanceCollection } from "./Instance/InstanceCollection"; export class Raycaster { static STEP_SIZE = 0.2; static getStructureBlocks(dimension, startLocation, direction, { maxDistance = 7, getFirst = true, collideWithWorldBlocks = true, useActiveLayer = true }) { const blocks = []; let location = startLocation; let distance = 0; while (distance < maxDistance) { const instance = instanceCollection.getInstanceAt(dimension.id, location, { useActiveLayer }); if (instance) { const block = instance.getBlock(instance.toStructureCoords(location)); if (block?.typeId !== 'minecraft:air') { blocks.push({ block, location, instance}); if (getFirst) break; } try { if (collideWithWorldBlocks && !dimension.getBlock(location)?.isAir) break; } catch (e) { if (e.name === 'LocationOutOfWorldBoundariesError') break; throw e; } } location = { x: location.x + (direction.x*this.STEP_SIZE), y: location.y + (direction.y*this.STEP_SIZE), z: location.z + (direction.z*this.STEP_SIZE) }; distance += this.STEP_SIZE; } // world.getDimension('minecraft:overworld').spawnParticle('minecraft:villager_happy', location); return blocks; } static getTargetedStructureBlock(player, { isFirst = true, collideWithWorldBlocks = true, useActiveLayer = true } = {}) { const startLocation = player.getHeadLocation(); const direction = player.getViewDirection(); const maxDistance = 7; const blocks = this.getStructureBlocks(player.dimension, startLocation, direction, { maxDistance, getFirst: isFirst, collideWithWorldBlocks, useActiveLayer }); if (blocks.length === 0) return void 0; return isFirst ? blocks[0] : blocks[blocks.length - 1]; } }