Update 2
Did some more work on moving blocks. Now they snap to the grid, it's obvious when they're being carried, and they won't be placed on walls or other blocks.
Obstacle detection tripped me up. I wrote code so that a block couldn't be dropped if there was a block at that point, but it kept detecting itself and refusing to be placed. Tip for Game Maker devs, if you're using position_meeting for collision detection and your code isn't working, try using place_meeting instead - that's the one that checks collisions for your object instance rather than a single point.
The next step is to rotate blocks. When the player clicks the right mouse button while holding the block, I want to rotate it by 90 degrees.
I'm completely stuck now, though. When I rotate a block's sprite, the collision mask changes in a way that doesn't match the rotation but which I can't figure out. Like so:
I suspect the sprite is rotating around the origin point incorrectly, or that the mask is cut off by the changed dimensions of the rotated sprite. The origin is in the top-left corner of the unrotated sprite, which is why it moves so much when it rotates.
But I can't figure out how to fix it. I can't find any helpful documentation or tutorials online, maybe because they're focusing on I could make separate sprites which are the original sprite rotated by 90, 180 and 270 degrees and change to those, but then I'd have to do that for every single type of block, and write arrays for each block to read to figure out what sprite to change to next. That doesn't appeal to me.
The simplest solution would be to not let the player rotate blocks. That would be fine, and probably easier to design puzzles around, but it's not quite as exciting. I'll sleep on this, and if I don't get any ideas, I'll just cut out block rotation press on with developing the rest of the game.