+ if (ds->three_d) {
+ /*
+ * In 3D mode, just locating the mouse click in the natural
+ * square grid may not be sufficient to tell which tower the
+ * user clicked on. Investigate the _tops_ of the nearby
+ * towers to see if a click on one grid square was actually
+ * a click on a tower protruding into that region from
+ * another.
+ */
+ int dx, dy;
+ for (dy = 0; dy <= 1; dy++)
+ for (dx = 0; dx >= -1; dx--) {
+ int cx = tx + dx, cy = ty + dy;
+ if (cx >= 0 && cx < w && cy >= 0 && cy < w) {
+ int height = state->grid[cy*w+cx];
+ int bx = COORD(cx), by = COORD(cy);
+ int ox = bx + X_3D_DISP(height, w);
+ int oy = by - Y_3D_DISP(height, w);
+ if (/* on top face? */
+ (x - ox >= 0 && x - ox < TILESIZE &&
+ y - oy >= 0 && y - oy < TILESIZE) ||
+ /* in triangle between top-left corners? */
+ (ox > bx && x >= bx && x <= ox && y <= by &&
+ (by-y) * (ox-bx) <= (by-oy) * (x-bx)) ||
+ /* in triangle between bottom-right corners? */
+ (ox > bx && x >= bx+TILESIZE && x <= ox+TILESIZE &&
+ y >= oy+TILESIZE &&
+ (by-y+TILESIZE)*(ox-bx) >= (by-oy)*(x-bx-TILESIZE))) {
+ tx = cx;
+ ty = cy;
+ }
+ }
+ }
+ }
+