//Called ClientSide public void OnUseOver(IPlayer byPlayer, BlockSelection blockSel, bool mouseBreakMode) { Cuboidf[] boxes = Circuit.GetCurrentSelectionBoxes(); //If true, something is wrong with selection boxes or the board was selected. if (blockSel.SelectionBoxIndex >= boxes.Length) { return; } //From the hit position and the face we can infere a voxel position without using selection box index //It works but could be refined Vec3f rotation = SignalsUtils.FacingToRotation(this.orientation, this.facing); Vec3f hitPos = blockSel.HitPosition.ToVec3f().Mul(16); BlockFacing selectionFacing = blockSel.Face; //We translate using the normal to avoid rounding and precision issues Vec3f hitPos2 = hitPos.AddCopy(selectionFacing.Normalf.NormalizedCopy().Mul(-0.5f)); //We need to apply rotation now RotateFromBEtoCircuit(ref hitPos2, ref selectionFacing, new Vec3f(8, 8, 8)); Vec3i voxelPos = new Vec3i((int)Math.Floor(hitPos2.X), (int)Math.Floor(hitPos2.Y), (int)Math.Floor(hitPos2.Z)); Cuboidf box = boxes[blockSel.SelectionBoxIndex]; Vec3i voxelBoxPos = new Vec3i((int)Math.Floor(box.MinX * 16), (int)Math.Floor(box.MinY * 16), (int)Math.Floor(box.MinZ * 16)); OnUseOver(byPlayer, voxelPos, voxelBoxPos, selectionFacing, mouseBreakMode); }