[0.5 stable] the "quadrants" house

This patch improves the “quadrants” variant of a house so that
it is reasonable (for example, no door in the middle of a room).
I post this as a bug report, not as a suggestion, because
the current code is just broken (the variable cw is used
in a wrong place).

— a/mapgen.cpp
+++ b/mapgen.cpp
@@ -1162,11 +1162,12 @@
case ot_house_south:
case ot_house_west:

  • // assumes that SEEX and SEEY are 12 or greater
    lw = rng(0, 4); // West external wall
    mw = lw + rng(7, 10); // Middle wall between bedroom & kitchen/bath
    rw = SEEX * 2 - rng(1, 5); // East external wall
    tw = rng(1, 6); // North external wall
  • bw = SEEX * 2 - rng(2, 5); // South external wall
  • bw = SEEY * 2 - rng(2, 5); // South external wall
    cw = tw + rng(4, 7); // Middle wall between living room & kitchen/bed
    for (int i = 0; i < SEEX * 2; i++) {
    for (int j = 0; j < SEEY * 2; j++) {
    @@ -1182,20 +1183,32 @@
    }
    switch(rng(1, 3)) {
    case 1: // Quadrants, essentially
  • mw = rng(lw + 5, rw - 5);
    cw = tw + rng(4, 7);
  • // living and kitchen
  • mw = rng(lw + 5, rw - 5);
    house_room(this, room_living, mw, tw, rw, cw);
    house_room(this, room_kitchen, lw, tw, mw, cw);
    ter_set(mw, rng(tw + 2, cw - 2), (one_in(3) ? t_door_c : t_floor));
  • rn = rng(lw + 1, cw - 2);
  • rn = rng(lw + 1, mw - 2);
    ter_set(rn , tw, t_window_domestic);
    ter_set(rn + 1, tw, t_window_domestic);
  • rn = rng(cw + 1, rw - 2);
  • rn = rng(mw + 1, rw - 2);
    ter_set(rn , tw, t_window_domestic);
    ter_set(rn + 1, tw, t_window_domestic);
  • mw = rng(lw + 3, rw - 3);
  • if (mw <= lw + 5) { // Bedroom on right, bathroom on left
  • rn = rng(cw + 2, rw - 2);
  • // Placement of the main door
  • if (one_in(2)) {
  • ter_set(rng(lw + 2, mw - 1), tw, (one_in(6) ? t_door_c : t_door_locked));
  • if (one_in(5))
  • ter_set(rw, rng(tw + 2, cw - 2), (one_in(6) ? t_door_c : t_door_locked));
    
  • } else {
  • ter_set(rng(mw + 1, rw - 2), tw, (one_in(6) ? t_door_c : t_door_locked));
  • if (one_in(5))
  • ter_set(lw, rng(tw + 2, cw - 2), (one_in(6) ? t_door_c : t_door_locked));
    
  • }
  • // bathroom and bedroom
  • if (rng(lw + 5, rw - 5) <= mw) { // Bedroom on right, bathroom on left
  • mw = rng(lw + 3, mw);
  • rn = rng(mw + 1, rw - 2);
    if (bw - cw >= 10 && mw - lw >= 6) {
    house_room(this, room_bathroom, lw, bw - 5, mw, bw);
    house_room(this, room_bedroom, lw, cw, mw, bw - 5);
    @@ -1209,9 +1222,10 @@
    house_room(this, room_bathroom, lw, cw, mw, bw);
    }
    house_room(this, room_bedroom, mw, cw, rw, bw);
  • ter_set(mw, rng(bw - 4, bw - 1), t_door_c);
  • ter_set(mw, rng(bw - 3, bw - 1), t_door_c);
    } else { // Bedroom on left, bathroom on right
  • rn = rng(lw + 2, cw - 2);
  • mw = rng(mw, rw - 3);
  • rn = rng(lw + 1, mw - 2);
    if (bw - cw >= 10 && rw - mw >= 6) {
    house_room(this, room_bathroom, mw, bw - 5, rw, bw);
    house_room(this, room_bedroom, mw, cw, rw, bw - 5);
    @@ -1225,33 +1239,35 @@
    house_room(this, room_bathroom, mw, cw, rw, bw);
    }
    house_room(this, room_bedroom, lw, cw, mw, bw);
  • ter_set(mw, rng(bw - 4, bw - 1), t_door_c);
  • ter_set(mw, rng(bw - 3, bw - 1), t_door_c);
    }
    ter_set(rn , bw, t_window_domestic);
    ter_set(rn + 1, bw, t_window_domestic);
    if (!one_in(3)) { // Potential side windows
    rn = rng(tw + 2, bw - 5);
  • ter_set(rw, rn , t_window_domestic);
  • ter_set(rw, rn + 4, t_window_domestic);
  • if (rn != cw && rn != bw - 4 && rn != bw - 5)
  •  ter_set(rw, rn    , t_window_domestic);
    
  • if (rn + 4 != cw && rn + 4 != bw - 4 && rn + 4 != bw - 5)
  •  ter_set(rw, rn + 4, t_window_domestic);
    
    }
    if (!one_in(3)) { // Potential side windows
    rn = rng(tw + 2, bw - 5);
  • ter_set(lw, rn , t_window_domestic);
  • ter_set(lw, rn + 4, t_window_domestic);
  • if (rn != cw && rn != bw - 4 && rn != bw - 5)
  •  ter_set(lw, rn    , t_window_domestic);
    
  • if (rn + 4 != cw && rn + 4 != bw - 4 && rn + 4 != bw - 5)
  •  ter_set(lw, rn + 4, t_window_domestic);
    
  • }
  • rn = rng(lw + 1, lw + 2);
  • if (ter(rn, cw) != t_floor)
  • ter_set(rn, cw, t_door_c);
    
  • if (cw + 1 > bw - 6 || one_in(4))
  • {
  • if (ter(rw - 2, cw) != t_floor)
    
  •   ter_set(rw - 2, cw, t_door_c);
    
    }
  • ter_set(rng(lw + 1, lw + 2), cw, t_door_c);
  • if (one_in(4))
  • ter_set(rw - 2, cw, t_door_c);
    else
  • ter_set(mw, rng(cw + 1, bw - 1), t_door_c);
  • if (one_in(2)) { // Placement of the main door
  • ter_set(rng(lw + 2, cw - 1), tw, (one_in(6) ? t_door_c : t_door_locked));
  • if (one_in(5))
  • ter_set(rw, rng(tw + 2, cw - 2), (one_in(6) ? t_door_c : t_door_locked));
    
  • } else {
  • ter_set(rng(cw + 1, rw - 2), tw, (one_in(6) ? t_door_c : t_door_locked));
  • if (one_in(5))
  • ter_set(lw, rng(tw + 2, cw - 2), (one_in(6) ? t_door_c : t_door_locked));
    
  • {
  • ter_set(mw, rng(cw + 1, bw - 6), t_door_c);
    }
    break;